이벤트 처리와 함수의 동작 방식을 이해하기 위해서 이번 포스트에서는 이벤트 버블링, 클로저, 그리고 이를 활용한 함수 생성에 대해 자세히 알아보겠습니다.

이벤트 버블링(Event Bubbling)

이벤트 버블링은 DOM에서 발생하는 이벤트 전파 방식 중 하나로, 이벤트가 발생한 요소에서 시작해 그 부모 요소로 전파되는 과정을 의미합니다. 예를 들어, 버튼 클릭 이벤트가 발생하면 그 이벤트는 버튼에서 시작하여 버튼의 부모 요소, 조부모 요소 등으로 전파됩니다. 이 과정을 통해 개발자는 특정 요소에서 발생한 이벤트를 부모 요소에서 처리할 수 있습니다.

예시 코드

document.getElementById('parent').addEventListener('click', function() {
    console.log('부모 요소 클릭됨');
});

document.getElementById('child').addEventListener('click', function() {
    console.log('자식 요소 클릭됨');
});

위 코드에서 자식 요소를 클릭하면 '자식 요소 클릭됨'이 출력되고, 그 후 '부모 요소 클릭됨'이 출력됩니다. 이러한 특징은 이벤트 위임(Event Delegation) 기법을 사용할 때 유용합니다.

이벤트 currentTarget vs target

이벤트 객체에는 targetcurrentTarget이라는 두 가지 속성이 있습니다.

  • target: 이벤트가 발생한 실제 요소를 가리킵니다.
  • currentTarget: 이벤트 리스너가 등록된 요소를 가리킵니다.

예시 코드

document.getElementById('parent').addEventListener('click', function(event) {
    console.log('target:', event.target);
    console.log('currentTarget:', event.currentTarget);
});

위 코드에서 부모 요소를 클릭하면 target은 클릭한 요소, currentTarget은 이벤트 리스너가 등록된 부모 요소를 가리킵니다.

클로저(Closure)

클로저는 함수가 자신의 외부 스코프에 접근할 수 있는 기능입니다. 즉, 함수가 생성될 때 그 함수가 정의된 환경을 기억하여, 나중에 호출될 때 그 환경에 접근할 수 있습니다. 클로저는 데이터 은닉, 상태 유지, 그리고 부분 적용과 같은 여러 가지 유용한 패턴을 가능하게 합니다.

예시 코드

function makeCounter() {
    let count = 0; // 클로저로 유지되는 상태

    return function() {
        count += 1;
        return count;
    };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2

위 코드는 makeCounter 함수가 클로저를 사용하여 count 변수를 기억하고, 이를 통해 호출할 때마다 카운터를 증가시킵니다.

커링(Currying)

커링은 여러 개의 인자를 받는 함수를 단일 인자 함수의 연쇄로 변환하는 기법입니다. 즉, 인자를 하나씩 받아서 함수를 반환하는 방식입니다. 이를 통해 함수의 재사용성을 높이고, 부분 적용을 쉽게 할 수 있습니다.

커링의 장점

  1. 함수의 이름을 지정하여 새로운 목적의 함수를 생성할 수 있다.
  2. 실행을 지연시킬 수 있다.

예시 코드

function add(a) {
    return function(b) {
        return a + b;
    };
}

const add10 = add(10);
const add100 = add(100);

console.log(add10(5));  // 15 ,1. 함수의 이름을 지정하여 새로운 목적의 함수를 생성할 수 있다.
console.log(add100(5)); // 105 ,1. 함수의 이름을 지정하여 새로운 목적의 함수를 생성할 수 있다.
function createCalculator(initialValue) {
    let value = initialValue;

    return {
      //2. 실행을 지연시킬 수 있다. , 지연시켜서 다른 동작을 하도록 구현할 수 있음
        add: function(num) {
            value += num;
            return value;
        },
        subtract: function(num) {
            value -= num;
            return value;
        },
        getValue: function() {
            return value;
        }
    };
}

const calculator = createCalculator(100);
console.log(calculator.add(50));      // 150
console.log(calculator.subtract(30));  // 120
console.log(calculator.getValue());    // 120

위 코드에서 createCalculator 함수는 초기값을 받아 여러 가지 계산을 수행할 수 있는 객체를 반환합니다. 이 객체는 add, subtract, getValue 메서드를 통해 값을 조작하고 조회할 수 있습니다.

Redux와 클로저

Redux는 상태 관리를 위한 라이브러리로, 미들웨어를 사용하여 비동기 작업이나 부가적인 기능을 추가할 수 있습니다. 다음은 Redux에서 클로저를 사용하는 예시입니다.

예시 코드

const redux = store => action => next => {
    console.log('액션:', action);
    return next(action);
};

위 코드는 액션이 발생할 때마다 로그를 남기는 미들웨어를 정의하는 코드입니다. 클로저를 통해 storeaction에 접근할 수 있습니다.

결론

이벤트 버블링을 통해 효율적으로 이벤트를 처리할 수 있으며, 클로저는 함수의 유연성을 높여줍니다.

profile
롤보다 개발이 재밌는 프론트엔드 개발자입니다 :D

0개의 댓글

관련 채용 정보