콜백함수가 무엇인지 알고 계신가요? 자세히 알아보기 전에 먼저 개념을 짚고 넘어가도록 하겠습니다

콜백함수란 다른 코드의 인자로 넘겨주는 함수를 말합니다.

어렵지 않은 개념이죠? 즉 콜백 함수를 넘겨받은 코드는 이 콜백 함수를 필요에 따라 적절히 실행하는 겁니다. 여기서 조금 눈여겨 보아야 하는 부분은 ‘필요에 따라 적절히’라는 문장입니다. 즉 콜백함수는 요청 함수가 원하는 시점에 작동합니다. 그때 요청한 함수가 콜백 실행의 제어권을 가지게 됩니다.이 제어권이 콜백의 핵심 요소 중 하나입니다. 이 중요성은 이름에서부터 찾아볼 수 있죠.

callback = call + back = 부르다 + 되돌아오다

이렇게 단어별로 나누면 원하는 시점에 되돌아와서 실행해달라는 요청을 하는 모양세죠. 이 요청은 제어권을 가진 호출함수가 하게되구요. 요청이 들어가는 순간 인자와 적절한 코드를 넘겨줍니다. 적절한 정보를 받은 콜백함수는 요청에 따라 호출 함수가 원하는 시점에 실행됩니다.

제어권 예시

계속 콜백 함수에 대한 제어권이 호출함수에 있다고 말했습니다. 이를 자세히 알아보기 위해 ㅁArray.map 메서드로 예시를 들어보겠습니다.

Array.map(callback(element, index){
	//do something
})

이렇게 구조가 이뤄졌다고 하죠. 여기서 콜백을 호출하는 함수는 map 메서드입니다. 때문에 메서드의 규칙에 따라 콜백의 첫 인자로 배열의 요소를 순서대로 담고 두번째 인자로 인덱스를 담는 규칙을 따라줘야 합니다. 이는 어떤 콜백이 오더라도 따라야 하죠. 이렇게 강제성을 가지는 이유는 map이 호출함수로서 콜백에 대한 제어권을 가지기 때문입니다.

콜백의 this

콜백에서 this는 자주 햇갈리는 개념입니다. 예를 들어 map은 두번째 인자로 지정해주지 않으면 전역을 나타내고, 지정해주면 지정한 요소가 this가 됩니다. 이벤트 메서드인 addEventListener의 경우는 지정할 필요 없이 호출한 주체인 HTML 엘리먼트는 가리킵니다. 이렇게 차이가 나는 것은 내부 동장의 차이입니다. 일반적으로 지정을 하면 변하는 콜백은 내부에 apply/call 메서드가 들어있습니다. 이들을 통해 명시적으로 this를 지정할 수 있는 거죠.

콜백으론 함수만 전달할 수 있다.

당연한 말인 것처럼 보입니다. 콜백 함수로 함수만 전달 가능하죠. 여기서 주의할 점은 함수가 객체의 메서드 형태로 전달되어도 매서드로서 작동하지 않는다는 것입니다. 즉 매서드라는 형식으로 가져오기는 가능하지만 개별 함수로서 콜백에 담기는 것입니다. 이런 이유 때문에 콜백 함수에 메서드를 담고 this를 호출해도 소속 객체가 나오지 않고 전역이 호출됩니다. 즉 담기는 함수는 온전히 함수만 담기기 때문이죠.

만약 콜백에서 소속 객체를 나타내주고 싶다면 어떻게 해야 할까요? ES5 이전에는 다양한 수단을 이용해 마치 this를 새롭게 선언한 것 처럼 보이도록 노력했습니다. 굉장히 번거로웠죠. 그러나 이제는 ES5에서 bind 메서드를 제공하면서 명시적으로 원하는 객체를 지정해 줄 수 있게 되었습니다. 즉 소속 객체를 나타내주길 원한다면 obj.method.bind(obj) 형식으로 써 주면되죠. **

정리

마무리한 콜백의 내용을 정리해볼까요?

  • 콜백은 다른 코드에 인자로 넘겨줌으로써 그 제어권도 위임한 함수입니다.
  • 제어권을 넘겨받은 코드는 다음과 같은 제어권을 가집니다.

    1) 콜백함수를 호출하는 시점을 스스로 판단해서 실행

    2) 호출시 인자로 넘겨줄 값들 및 그 순서를 정합니다.

    3) this가 무엇을 바라보아야 할지 정해져 있거나 정해야 하는 경우를 만듦니다. 임의로 정하고 싶다면 bind 를 쓰면 됩니다.

  • 어떤 함수에 인자로 메서드를 전달해도 이는 결국 함수로서 작동합니다.

이렇게 정리할 수 있을 것 같습니다. 콜백은 자주 쓰이는 개념이니 정리된 내용이라도 반복해서 학습하는 습관을 들이는게 좋겠네요.