클로저와 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 가 출력된다.