[JS] Callback function

Chipmunk_jeong·2021년 8월 5일
0

TIL

목록 보기
57/62
post-thumbnail

해당 블로깅은 인프런의 강의를 들으며 공부한 내용을 정리한 글입니다.
ES5 기준 핵심 내용을 공부하면서 작성하는 블로깅

제어권


콜백 함수는 함수의 실행 제어권을 넘긴다.

1. 실행 시점

콜백함수는 실행 시점의 제어권을 넘겨준다.

var cb = function () {
  console.log('1초 실행');
  }
setInterval(cb, 1000);

cb라는 함수가 setInterval의 인자(콜백함수)로 넘겨준 이상 실행 제어권은 setInterval에게 넘겨주게 된다.
이 때 실행시점은 1초 마다 한번씩이라는 setInterval이 설정한 주기로 실행이 된다.

2. 인자

콜백함수의 인자는 콜백으로 넘겨줄때 정해진 인자를 받게 된다.

var arr = [1, 2, 3, 4, 5];
var entries = [];
arr.forEach(function(value, index) {
  entries.push([i, v, this[i]]);
}, [10, 20, 30, 40, 50]);
console.log(entries);
//[ [0, 1, 10], [1, 2, 20], [2, 3, 30]....

forEach의 콜백함수는 value, index, thisArg를 인자로 받기로 약속(정의)되어 있다. 이처럼 콜백함수로 전달을 한다면 전적으로 실행하는 함수(메서드)에서 인자를 정해주고, 해당 가이드를 맞춰 작성해야한다. 만약 콜백함수의 인자를(index, value)로 정의해봤자 index자리에는 value가 value자리에는 index가 할당될 것이다.

3. this


앞서 this게시글에서 작성했듯이 콜백함수로써의 this는 전역객체이다.(ES5기준) 하지만 배열 메서드라던가 이미 정의된 함수에 콜백함수로 넘길때는 this바인딩되어있는 경우도 많다.

// 1. 이벤트 리스너로 콜백함수
document.querySeletor('div');
function handleClickH1(event) {
  console.log(this);
  console.log(event);
}
document.addEventListenet('click', handleClickH1);

클릭 이벤트를 생성하고 콜백함수로 정의해둔 함수를 인자로 넘겨주고 클릭을 한다면 위처럼 this값이 HTMLElement가 나오게되고, 정해진 event객체가 인자로 고정으로 들어온다.
원래라면 콜백함수의 this는 전역객체지만 this가 바인딩 되어있기 때문에 결과가 위처럼 나오게 된다.
또한, 배열 메서드는 인자로 this바인딩할 대상을 받을 수 있다.

var arr = [1, 2, 3, 4];
var mapping = arr.map(function(value, index){
  return value * this[index];
}, [10, 20, 30, 40]);
console.log(mapping);
// [10, 40, 90, 160]

forEach, filter, map등 배열의 메서드는 2번째 인자로 this바인딩 대상을 입력받을 수 있다. 옵셔널 인자라 생략이 가능하다. 이렇게 기본적으로 this가 바인딩되어있는경우도, 또는 바인딩될 타겟을 받는경우도 있을 수 있기때문에 콜백함수에서의 this는 대상이 계속 유동적으로 변하게 된다.

콜백함수의 특징


1. 다른 함수(A)의 인자로 콜백함수(B)를 전달하면, A가 B의 제어권 을 가지게 된다

2. 특별한 요청(bind)이 없는 한 A에 미리 정해놓은 방식 에 따라 B를 호출한다.

3. 미리 정해놓은 방식이란, 어떤 시점 에 콜백을 호출할지, 인자 에는 어떤 값들을 지정할지, this 에 무엇을 바인딩 할것인가이다.

주의할 점
callback은 함수이다.
함수로써 callback이 호출될때 this의 값은 전역객체이다.

var arr = [1, 2, 3, 4, 5];
var obj = {
  numbers: [ 1, 2, 3 ],
  printValues: function(value, index) {
    if(this.numbers) {
      console.log(this.numbers, value, index);
    } else {
      console.log(this, value, index);
    }
  }
};

메서드로 호출

obj.printValues(1, 2);
// 메서드로 호출되었을 때 this는 obj가 되고
// [1, 2, 3], 1, 2가 출력이된다.

콜백함수로 호출

arr.forEach(obj.printValues);
// 콜백함수로 넘어가면 this는 전역객체가 되기때문에
// `window 객체`, 1, 0
// `window 객체`, 2, 1
// `window 객체`, 3, 2
...

위 처럼 호출 방식에 따라 정의해놓은 함수의 this가 달라지니 주의할 것
해결법
arr.forEach(obj.printValues.bind(obj)
or
arr.forEach(obj.printValues, obj)

profile
Web Developer

0개의 댓글