제어권도 함께 위임한 함수입니다.this는 기본적으로 전역객체를 참조하지만, 제어권을 넘겨받은 코드에서 콜백함수에 별도로 this가 될 대상을 지정할 수있습니다.Array.prototype.map = function (callback, thisArg) {
let mappedArr = [];
for (let i = 0; i < this.length; i++) {
let mappedValue = callback.call(thisArg || window, this[i], i, this);
mappedArr[i] = mappedValue;
}
return mappedArr;
};
다음과 같이 this 를 명시적으로 바인딩하기 때문에 this 에 다른값이 담기는것을 확인할 수 있습니다.
당연한 소리라고 생각할 수 있지만
만약 객체의 메서드를 전달하더라도 메서드가 아닌 함수로 호출되는것을 확인할 수 있습니다.
let 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 ...
obj.logValues(1, 2) 로 호출했을때는 this는 obj를 가리키지만forEach 를 사용하여 콜백함수로 불렀을때는 메서드로서 호출이 아닌 함수로 호출되었기 때문에 this가 전역객체를 바라보게 됩니다.콜백함수를 익명함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들정도로 깊어지는 현상
동기의 반댓말로 현재 실행 중인 코드의 완료 여부와 무관하게 다음 코드로 넘어가는 것입니다.
setTimeout: 사용자의 요청에 의해 특정시간 경과까지 실행 보류addEventListener: 사용자의 개입이 있을때 함수실행하도록 대기XMLHttpRequest: 별도의 대상에 요청하고 응답이 왔을때 실행하도록 대기
콜백지옥 예시
setTimeout(function (name) {
var coffeeList = name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
setTimeout(function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
},500,"카페라떼");
},500,"카페모카");
},500,"아메리카노");
},500,"에스프레소");
Promise, Generator, async/await를 사용해서 벗어날 수 있습니다.