클로저와 this 바인딩

const object1 = (() => {
    let state = 1;
    
    return {
        state: 2,
        test() {
            console.log(state, this.state); // 1 2
        }
    };
})();

object1 은 IIFE 로 즉시 종료하지만

반환하는 객체의 메서드(test)가 state 변수를 참조하므로 기억된다. (test 는 클로저, state 는 자유 변수가 된다.)

또 반환하는 객체(object1) 는 this 로 객체가 가진 속성(state) 에 접근할 수 있도록 제공한다.

const test = object1.test;

test(); // 1 undefined

test 변수에 object1.test 메서드의 참조를 저장하고 출력해보면 this 참조가 끊어진다.

메서드 형태가 아닌 일반 함수 형태로 호출하기 때문이다.

이렇게 this 는 호출 방식에 영향을 받는다.

const object2 = (() => {
  let state = 3;
  
  return {
    state: 4,
    test2(callback) {
      callback();
    },
  };
})();

object2.test = object1.test;

object2.test();  // 1, 4

동일하게 object2 는 test2 라는 클로저로 state: 3 값을 기억한다.

또 state: 4 라는 속성을 가진다.

object2.test 라는 속성을 정의하는데. object1.test 메서드의 참조를 저장하면 어떻게 될까.

object2.test() 는 this.state 를 출력하게 되고 this 는 object2 라는 컨텍스트를 가리키게 된다.

object2.test2(object1.test); // 1 undefined

object2.test2 는 callback 이라는 인자를 받아서 출력하고 있는데.

object1.test 메서드의 참조를 받아서 호출한다. 이때 callback() 은 단순히 일반 함수 호출이 된다.

this 는 전역 컨텍스트를 가리키므로 undefined 가 출력된다.