콜백 함수
다른 코드의 인자로 넘겨주는 함수. 그 제어권도 함께 위임함. 콜백 함수를 위임받은 코드는 자체적으로 내부 로직에 의해 이 콜백 함수를 적절한 시점에 실행
콜백함수를 넘겨받는 코드: forEach, setTimeout, map..
콜백 함수의 this
- 콜백 함수도 함수이기 때문에 기본적으로는 this가 전역객체를 참조한다.
- 예외로 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조한다.
this binding: call, apply, bind - 콜백 함수로 어떤 객체의 메서드를 전달하더라도, 그 메서드는 메서드가 아닌 함수로 호출해요. (그 메서드가 가리키는 함수만 전달한 것이기 때문에 메서드의 기존 객체와는 연관이 없음)
- addEventListener는 내부에서 콜백 함수를 호출할 때, call 메서드의 첫 번째 인자에 addEventListener메서드의 this를 그대로 넘겨주도록 정의돼 있어요(상속)
var obj = {
vals: [1, 2, 3],
logValues: function(v, i) {
console.log(this, v, i);
}
};
//method로써 호출
obj.logValues(1, 2);
//callback => obj를 this로 하는 메서드를 그대로 전달한게 아니에요
//단지, obj.logValues가 가리키는 함수만 전달한거에요(obj 객체와는 연관이 없습니다)
[4, 5, 6].forEach(obj.logValues);
https://console-log.tistory.com/76
this 바인딩 - call, apply, bind
실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체 실행 컨텍스트의 구성요소 : VariableEnvironment, LexicalEnvironment, ThisBindings this는 실행 컨텍스트가 생성될 때 결정돼서 즉, this를 b
console-log.tistory.com
콜백 지옥
콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 헬 수준인 경우를 말함
주로 이벤트 처리 및 서버 통신과 같은 비동기적 작업을 수행할 때 발생
[map함수 직접 만들어보기 예제]
// Array에 있는 prototype에(Array.prototype)에 쓰고싶은 함수 만들어주면, 어떤 배열이던지간에 만든대로 함수처럼 호출해서 쓸 수 있음
// 원조map은 항상 콜백 함수를 받으니까 짜가map도 첫번째 인자로 callback을 넣어줌
// 원조map은 두번째 인자로 this를 받음. 짜가map은 thisArg라고 해보겠음
Array.prototype.map123 = function (callback, thisArg) {
// 원조map은 결론적으로 새로운 객체를 return하니까
// return할 그 객체를 미리 선언해놓겠음
// map 함수에서 return할 결과 배열
var mappedArr = [];
// for문을 돌리면서 하나하나씩 콜백함수를 실행할거임
// 실행해서 가공할꺼
// 아래의 this는 map123의 호출주체인 배열[1, 2, 3]이 됨
for (var i = 0; i < this.length; i++) {
// callback() : 받은 콜백함수를 수행
// 할 때 this binding을 해주기위해서 call즉시실행함수를 사용해서
// thisArg || global : 만약에 thisArg가 들어왔으면 그걸쓰고 없으면 그냥 global로 해주
// this[i] : 원래 들어갔어야 할 두번째 인자는 for문에 해당하는 배열인자를 넣어줘
var mappedValue = callback.call(thisArg || global, this[i]);
// 제어권을 넘겨받을 코드에서 call/apply 메서드의 첫 번째 인자에서 콜백 함수 내부에서 사용될 this를 명시적으로 binding 하기 때문에 this에 다른 값이 담길 수 있는 거 !
// mappedArr의 i번째에다가 mappedValue를 넣어줘
mappedArr[i] = mappedValue;
}
// for문으로 완성된 mappedArr를 returen해줘
return mappedArr;
};
var newArr = [1, 2, 3].map123(function (number) {
return number * 2;
});
console.log(newArr);
'JavaScript' 카테고리의 다른 글
| Class (0) | 2023.05.28 |
|---|---|
| 비동기 작업의 동기적 표현 - Promise, Generator, Async/await (1) | 2023.05.28 |
| this 바인딩 - call, apply, bind (0) | 2023.05.25 |
| 실행컨텍스트(스코프, 변수, 객체, 호이스팅) (2) | 2023.05.25 |
| 깊은 복사 (0) | 2023.05.25 |