다른 코드의 인자로 넘겨주는 함수 == 제어권을 넘겨준다.
콜백 함수를 넘겨받은 코드는 콜백 함수를 필요에 따라 적절한 시점에 실행.
`setInterval(func, delay[], param1, param2, ...);
var count = 0;
var cbFunc = function() {
console.log(count);
if(++count > 4) clearInterval(timer);
};
var timer = setInterval(cbFunc, 300);
// 0 (0.3초)
// 1 (0.6초)
// 2 (0.9초)
// 3 (1.2초)
// 4 (2.5초)
code | 호출 주체 | 제어권 |
---|---|---|
cbFunc(); | 사용자 | 사용자 |
setInterval(cbFunc, 300); | setInterval | setInterval |
Array.prototype.map(callback[, thisArg])
callback: function(currentValue, index, array)
callback의 function(index, currentValue, array) 바꾸어도
정해진 문법규칙에 의해 동작한다.
var newArr = [10, 20, 30].map(function (currentValue, index) {
console.log(currentValue, index);
return currentValue + 5;
});
// 10 0 (출력 후 리턴 : 15)
// 20 1 (출력 후 리턴 : 25)
// 30 2 (출력 후 리턴 : 35)
// [15, 25, 35] (newArry)
콜백 함수도 함수이기 때문에
기본적으로 this가 전역객체를 참조하지만,
제어권을 넘겨받을 코드에서
콜백 함수에 별도로 this가 될 대상을 지정한 경우에는
그 대상을 참조하게 된다.
Array.prototype.map = function (callback, thisArg) {
var mappedArr = [];
for (var i = 0; i < this.length; i ++) {
var mappedValue = callback.call(thisArg || window, this[i], i, this);
mappedArr[i] = mappedValue;
}
return mappedArr;
};
1) setTimeout은 내부에서 콜백 함수를 호출할 때
call 메서드의 첫 번째 인사에 전역객체를 넘기기 때문에
this === 전역객체
2) forEach는 별도의 인자로 this를 넘겨주지 않으면
this === 전역객체
3) addEventListener는 내부에서 콜백 함수를 호출할 때
call 메서드의 첫 번째 인자에 addEventListener 메서드의 this를 그대로 넘기도록 정의
this === 콜백 함수 내부에서의 this가 addEventListener 호출한 주체인 HTML 엘리먼트
// 1. this : Window { ... }
setTimeout(function () { console.log(this); }, 300);
// 2. this : Window { ... }
[1, 2, 3, 4, 5].forEach(function (x) {
console.log(this);
});
// 3. this : <button id="a">클릭</button>
// Mouse Event { isTrusted: true, ... }
// addEventListener 메서드는 자신의 this를 상속하도록 되어있다.
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function (e) {
console.log(this, e);
});
콜백 함수로 어떤 객체의 메서드를 전달하더라도
그 메서드는 메서드가 아닌 함수로서 호출된다.
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
////////////////////////////114