코어 자바스크립트를 읽고 스터디 세션에서 공유를 위해 정리한 글입니다.
다른 코드(함수 또는 메서드)에게 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수이다.
→ 제어권(함수의 실행 등…)과 관련이 깊다.
콜백함수의 경우 제어권을 가진 다른 코드에 호출 시점에 대한 제어권을 넘긴다.
// 디바운싱
var timer;
var cbFunc = function() {
// do something...
}
document.querySelector('#input').addEventListener('input', function(e) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(cbFunc, 200);
});
// 스로틀링
var timer;
document.querySelector('#input').addEventListener('input', function(e) {
if (!timer) {
timer = setTimeout(cbFunc, 200);
}
});
code | 호출 주체 | 제어권 |
---|---|---|
cbFunc(); | 사용자 | 사용자 |
setInterval(cbFunc, 200); | setInterval | setInterval |
콜백함수의 경우 제어권을 가진 다른 코드에 인자의 규칙에 대한 제어권을 넘긴다.
var newArr = [1, 2, 3].map(function (currentValue, index) {
return currentValue + 5;
})
console.log(newArr);
// [6, 7, 8]
Array.prototype.map(callback[, thisArg])
callback: function(currentValue, index, array)
- 콜백함수도 함수 → 기본적으로 this는 전역객체
- 제어권을 넘겨받을 코드에서 별도로 this 지정 → 지정한 대상 참조
Array.prototype.map = function(callback, thisArg){
var mappedArr = [];
for (var i = 0; i < mappedArr.length; i++){
var mappedValue = callback.call(thisArg || Window, this[i], i, this);
mappedArr.push(mappedValue);
}
return mappedArr;
}
document.body.querySelector('#a').addEventListener('click', function (e) {
console.log(this); // <button id="a">클릭</button>
})
콜백 함수는 어떤 객체의 메서드를 전달하더라도 메서드가 아닌 함수로 호출된다.
var obj = {
vals: [1, 2, 3],
logValues: function (v, i) {
console.log(this, v, i);
}
}
obj.logValues(1, 2); // obj { ... }, 1, 2
[4, 5, 6].forEach(obj.logValues) // Window { ... }, x, x ...
var obj1 = {
name: "obj1",
func: function () {
var self = this;
return function () {
console.log(self.name);
};
},
};
var callback = obj1.func();
setTimeout(callback, 300); // obj1
var obj1 = {
name: "obj1",
func: function () {
var self = this;
return function () {
console.log(self.name);
};
},
};
var obj2 = {
name: "obj2",
func: obj1.func,
};
var callback1 = obj1.func();
setTimeout(callback1, 300); // obj1
var callback2 = obj2.func();
setTimeout(callback2, 300); // obj1
var obj1 = {
name: "obj1",
func: function () {
console.log(this.name);
},
};
var obj2 = {
name: "obj2",
};
setTimeout(obj1.func.bind(obj1), 300); // ojb1
setTimeout(obj1.func.bind(obj2), 300); // ojb2
var coffeeList = '';
var addEspresso = function (name) {
coffeeList = name;
console.log(coffeeList);
setTimeout(addAmericano, 500, '아메리카노');
}
var addAmericano = function (name) {
coffeeList += ', ' + name;
console.log(coffeeList);
setTimeout(addMocha, 500, '카페모카');
}
var addMocha = function (name) {
coffeeList += ", " + name;
console.log(coffeeList);
};
setTimeout(addEspresso, 500, '에스프레소')
var addCoffee = function (name) {
return function (prevName) {
return new Promise(function (resolve) {
setTimeout(function () {
var newName = prevName ? (prevName + ', ' + name) : name;
console.log(newName);
resolve(newName);
}, 500);
});
}
}
addCoffee("에스프레소")()
.then(addCoffee("아메리카노"))
.then(addCoffee("카페모카"))
.then(addCoffee("카페라떼"));
var addCoffee = function (prevName, name) {
setTimeout(function () {
coffeeMaker.next(prevName ? prevName + ', ' + name : name);
}, 500);
}
var coffeeGenerator = function* () {
var espresso = yield addCoffee('', '에스프레소')
console.log(espresso);
var americano = yield addCoffee(espresso, '아메리카노')
console.log(americano);
var mocha = yield addCoffee(americano, '카페모카')
console.log(mocha);
var latte = yield addCoffee(mocha, '카페라떼')
console.log(latte);
}
var coffeeMaker = coffeeGenerator();
coffeeMaker.next();
*
이 붙은 함수가 Generator 함수이다.var addCoffee = function (name) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(name);
}, 500);
});
}
var coffeeMaker = async function () {
var coffeeList = '';
var _addCoffee = async function (name) {
coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);
}
await _addCoffee('에스프레소');
console.log(coffeeList);
await _addCoffee("아메리카노");
console.log(coffeeList);
await _addCoffee("카페모카");
console.log(coffeeList);
await _addCoffee("카페라떼");
console.log(coffeeList);
}
coffeeMaker();