자바스크립트의 컨텍스트 바인딩 this의 4가지 동작방식을 알아보자.
function 키워드를 쓴 함수. = 그냥 함수를 호출할 때
함수 선언식을 사용하면 this 는 전역객체 ( window ) 와 바인딩이 된다. 단, strict mode에서는 에러발생
function foo () {
console.log(this.color);
}
var color = 'pink';
foo(); // pink
함수 호출시 객체의 프로퍼티로 접근해 실행하는 암시적 바인딩이다.
객체 obj의 프로퍼티 foo에 foo라는 함수의 참조를 할당하고 객체를 통해 foo를 호출하면 객체를 바인딩한다.
function foo () {
console.log(this.color);
}
const obj = {
color : 'pink',
foo : foo
}
obj.foo(); // pink
예제에서는 obj가 this로 지정된것이다.
function foo () {
console.log(this.color);
}
const obj = {
color : 'pink',
foo : foo
}
bar = obj.foo();
color = 'lemon';
bar(); // lemon
단, 위의 코드와같이 bar = obj.foo( ); 는 주소값을 저장한 것이므로 기본 바인딩 규칙을 따르게되어 this는 전역 컨텍스트에 바인딩된다.
자바스크립트의 내장함수 call, apply, bind를 사용하여 명시적으로 this가 어디에 바인딩 할 것인지 정해준다.
call
, apply
: obj를 this로 바인딩해서 호출해라. ( 한번호출할때 this를 바인딩해서 호출해라 )
bind
: 새로운 함수를 만들어서 호출해라.
function foo () {
console.log(this.color);
}
const obj = {
color : 'pink'
}
//obj.foo(); << 위의것과 비교
foo.call(obj); // 'pink'
class나 생성자 함수를 이용해 인스턴스를 만들 때 this 가 인스턴스에 바인딩 되도록 한다.
function Pen(color) {
this.color = color;
this.pick = function(){
console.log(this.color);
}
}
const pen1 = new Pen('pink');
pen1.pick(); // pink
ES6문법인 화살표함수 와 setTimeout 콜백 함수의 예외사항이 있다.
setTimeout 콜백함수는 setTimeout이 호출하기 때문에 setTimeout에 의존적이다.
따라서 콜백함수의 this는 전역 객체로 바인딩 된다.
function hello() {
setTimeout(function callback(){ console.log(this.name) })
}
const obj = {
name: 'Kim',
hello: hello
};
const name = 'Lee'
hello(); // 'Lee'
obj.hello(); // 'Lee'
hello.call({name: 'chris'}); // 'Lee'
화살표함수는 정적 바인딩이다.
코드상 상위 블록의 컨택스트를 this로 바인딩한다.
function hello() {
setTimeout(() => {
console.log(this.name)
})
}
const obj = {
name: 'Kim',
hello: hello
};
const name = 'Lee'
hello(); // 'Lee'
obj.hello(); // 'Kim'
hello.call({name: 'Choi'}); // 'Choi'
여기서 주의할거는 setTimeout 함수때문에 바인딩이 다른것이 아니라 setTimeout 함수 사용 할 때, 콜백함수와 화살표함수의 this 바인딩이 다른것이다.