콜백 함수는 다른 코드(함수 또는 메서드)에게 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수
this에 대해 공부할 때,
콜백함수에서 this는 해당 콜백함수의 제어권을 가지는 코드에 따라 달라진다고 공부 했다.
ex)
setTimeout(function() {console.log(this);}, 300); // (1)
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function(e) {
console.log(this, e); // (2)
});
(1)의 setTimeout
은 별도의 this 지정이 없다. 따라서 전역객체 반환
(2)의 addEventListener
는 콜백 함수를 실행 할 때 자신의 this를 상속하도록 되어있다.
따라서 .
앞 부분을 this로 반환한다.
이처럼 콜백함수는 제어권과 관련이 깊다.
setInterval(func, 500)
func는 사용자가 아닌 setInterval
이 정해진 시점에 실행한다.
호출 시점에 대한 제어권을 넘겨 받았다고 할 수 있다.
리액트로 개발하면서 수도 없이 썼던 map
함수를 살펴보자
Array.prototype.map(callback[, thisArg])
callback: function(currentValue, index, array)
callback
함수에 인자를 어떤 순서로 넘길지는 map
에 정의되어 있다.
콜백 함수가 사용자가 아닌 map
메서드이므로 전달하는 인자의 순서도 전적으로 map
메서드에 달린 것이다.
콜백함수는 '함수'로 실행된다. 당연한 이야기겠지만 아래와 같은 경우를 살펴보자
var obj = {
vals: [1, 2, 3],
logValues: function(v, i) {
console.log(this, v, i);
}
};
obj.logValues(1, 2); // { vals: [1, 2, 3], logValues: f } 1 2
[4,5,6].forEach(obj.logValues);
// Window { ... } 4 0
// Window { ... } 5 1
// Window { ... } 6 2
obj.logValues
는 메서드로 실행되었으나
forEach
에 의해 콜백함수로 실행된 obj.logValues
는 함수로 실행되었다.
따라서, this
는 전역객체를 참조한다.
var obj1 = {
name: 'obj1',
func: function (){
console.log(this.name);
}
};
setTimeout(obj1.func.bind(obj1), 1000);
var obj2 = { name: 'obj2' };
setTimeout(obj1.func.bind(obj2), 1500);
bind
를 사용해서 원하는 값으로 this를 할당 할 수 있다.