출저
- 코어자바스크립트 - 정재남
고차함수의 인자는 콜백함수 이다.
다른 함수의 내부로 전달되는 함수가 콜백함수.
비동기 처리에 활용되는 함수.
제어권
과 관련이 깊다.
콜백 함수의 제어권을 넘겨받은 코드(함수 또는 메서드)는 콜백 함수 호출 시점에 대한 제어권을 가진다.
그럼, 어떤 제어권을 말하는가??
콜백 함수의 제어권을 넘겨받은 코드는 콜백 함수 호출 시점에 대한 제어권
을 가진다.
let count = 0
let cbFunc = function () {
console.log(count)
if (++count){
clearIntercal(timer)
}
}
let timer = setIntercal(cbFunc, 300)
// 0 (0.3초)
// 1 (0.6초)
// 2 (0.9초)
// 3 (1.2초)
// 4 (1.5초)
cbFunc()
와 같이 바로 실행될 때와는 다르게 setIntercal(cbFunc, 300)
와 같이 setIntercal 안에 있을때는 실행시키는 주체가 다르다.콜백 함수의 제어권을 넘겨받은 코드는 콜백 함수를 호출할 때 인자에 어떤 값들을 어떤 순서
로 넘길 것인지에 대한 제어권을 가진다.
arr.map(콜백(첫 번째 인자, 두 번째 인자, 세 번째 인자))
은 이미 콜백함수를 받는다는 것이 약속되어 있고 그 콜백함수 안에 오는 첫 번째 인자는 map() 이 실행되는 대상의 arr 요소 하나 하나가 오게 될 것이고, 두 번째 인자는 index, 세 번째 인자는 실행되어 지는 arr가 오게 된다. 라는 약속이 이미 되어 있다.제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this 가 될 대상을 지정한 경우가 아닌 경우에는 콜백함수도 함수이기 때문에 기본적으로 this는 전역객체를 참조
한다.
setTimeout(function () {console.log(this)}, 300);
// Window {...}
[1, 2, 3, 4, 5].forEach(function (x){console.log(this)});
// Window {...}
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function (e){console.log(this, e)});
// <button id="a">클릭</button>...
이 문장은 당연한 것 같지만 콜백함수 단원의 관점에서 얘기해보자면,
함수의 this 는 전역을 가리킨다. this 단원에서 배웠듯이 함수는 객체안에 할당되어 있더라도 호출되는 방식에 따라 (obj.function 과 같이 객체로 불리는 경우) 가 아닌 이상은 this 가 전역을 가리킨다.
위와 같은 방식을 콜백 함수도 따른다는 말이 콜백함수도 함수다 라는 말로 표현된 것 같다.
이 얘기는 참고로 this 단원에서도 잠깐 언급되었었다.
위의 말이 계속 반복되고 있지만 다른 말로 정리해 보자면, 객체의 메서드를 콜백 함수로 전달하면 해당 객체를 this 로 바라볼 수 없게 된다.
콜백 함수 내부에서 this 가 객체를 바라보게 하고 싶다면?
let obj1 = {
name: 'obj1',
func: function (){
console.log(this.name)
}
}
setTimeout(obj1.func.bind(obj1), 1000) //obj1
let obj2 = {name:'obj2'}
setTimeout(obj1.func.bind(obj2), 1500) //obj2
콜백 지옥(callback hell) 은 콜백 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상