1. 콜백함수
콜백함수는 다른 코드의 인자로 전달되어 그 코드 내에서 호출되는 함수를 뜻한다.
기초문법에서 배운 setTimeout, foreach도 콜백함수이다.
예시)
// setTimeout
setTimeout(function() {
console.log("Test");
}, 1000);
// forEach
const numbers = [6, 7, 8, 9, 10];
numbers.forEach(function(number) {
console.log(number);
});
1 - 1 제어권(호출 시점)
콜백함수는 호출 시점에 대한 제어권을 갖는다.
콜백 함수의 제어권을 받은 코드(setinterval) : 반복해서 매개변수로 받은 콜백함수의 로직을 수행
let count = 0;
// cbFunc라는 이름의 콜백 함수를 정의
let TestFunc = function() {
console.log(count);
// count를 1 증가시키고, 6보다 크면 타이머를 중지
if (++count > 5) clearInterval(timer);
}
// 300밀리초마다 cbFunc 함수를 실행하는 타이머를 설정
let timer = setInterval(TestFunc , 500);
1 - 2 제어권(인자)
// index, currentValue : 사람이 이해할 수 있는 변수명(값)
let newArr = [1, 2, 3].map(function(currentValue, index){
console.log(currentValue, index);
return currentValue + 10;
});
console.log(newArr);
currentValue와 index 순서를 바꾸면 사람처럼 이해할 수 없어 의도하지 않은 값이 나온다.
1 - 3 제어권(this)
this는 전역 객체를 참조한다.
하지만 예외 사항이 있다. 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this 대상을 정한경우는
그 대상을 참조한다.
for (var i = 0; i < this.length; i++) {
// call의 첫 번째 인자는 thisArg가 존재하는 경우는 그 객체, 없으면 전역객체
// call의 두 번째 인자는 this가 배열일 것(호출의 주체가 배열)이므로,
// i번째 요소를 넣어서 인자로 전달
var mappedValue = callback.call(thisArg || global, this[i]);
mappedArr[i] = mappedValue; // callback 함수 결과
}
return mappedArr;
};
1 - 4 콜백 함수 도 함수다
콜백 함수로 객체의 메서드를 전달해도, 매서드가 아닌 함수로 호출 한다.
2가지 속성 (values, logvalue)
var obj = {
vals: [7, 8, 9],
logValues: function(v, i) {
console.log(">>> test starts");
if (this === global){
console.log("this가 global입니다. 원하지 않는 결과") // this가 전역객체인 경우 경고 메시지
}else{
console.log(this, v, i); // this가 obj 객체인 경우 this와 인자 v, i 출력
console.log(">>> test ends");
}
};
//method로써 호출
obj.logValues(3, 4);
// callback => obj를 this로 하는 메서드를 그대로 전달한게 아니에요
// 단지, obj.logValues가 가리키는 함수만 전달한거에요(obj 객체와는 연관이 없습니다)
// foreach, map, filter
[4, 5, 6].forEach(obj.logValues); // this는 전역객체가 되어서 "this가 global입니다. 원하지 않는 결과" 출력
1 - 5 this에 다른 값 바인딩
1 - 5 - 1 전통적 방식(closure)
현재 함수가 끝나도 영향을 미친다.
(1) 강제로 this 를 제어하는 방식
var obj1 = {
name: 'obj1',
func: function() {
var self = this; //이 부분!
return function () {
console.log(self.name);
// 단순히 함수만 전달한 것이기 때문에, obj1 객체와는 상관이 없다.
// 메서드가 아닌 함수로서 호출한 것과 동일
var callback = obj1.func();
setTimeout(callback, 1000);
(2) 첫 번째 예시를 재활용한 방식
var obj1 = {
name: 'obj1',
func: function() {
var self = this; //이 부분!
return function () {
console.log(self.name);
};
}
};
----------------------------------------------------------------------
// 위의 obj1의 func를 직접 obj2와 obj3에 대입해보면 더 보기 쉽다
var obj2 = {
name: 'obj2',
func: obj1.func
};
var callback2 = obj2.func();
setTimeout(callback2, 1500);
var obj3 = { name: 'obj3' };
var callback3 = obj1.func.call(obj3);
setTimeout(callback3, 2000);
(3) bind 메서드 활용 (1), (2)번보다 좋은 방법
// this를 바인딩해서 새로운 함수를 리턴
var obj1 = {
name: "obj1",
func: function () {
console.log(this.name);
},
};
// var boundObj1 = obj1.func.bind(obj1);
// setTimeout(boundObj1, 1000); // 이 두줄로 바꿀수있음
var obj2 = { name: 'obj2' };
//함수 자체를 obj2에 바인딩
//obj1.func를 실행할 때 무조건 this는 obj2로 고정해줘!
// 어떤 this든 원하는대로 바인드할수있다는걸 보여주는 코드
setTimeout(obj1.func.bind(obj2), 1500);
'TIL' 카테고리의 다른 글
TIL 240823 (로그라이크 기능 추가) (0) | 2024.08.23 |
---|---|
TIL 240821 (콜백 함수 2) (0) | 2024.08.21 |
TIL 240816 (데이터 타입[심화]) (0) | 2024.08.16 |
TIL 240814 (자바스크립트 기초문법 다지기 3) (0) | 2024.08.14 |
TIL 240813 (자바스크립트 기초문법 다지기 2) (0) | 2024.08.13 |