💻 JavaScript/기초 문법

JS 문법 종합: 콜백 함수

seheej 2024. 8. 6. 09:55

콜백 함수란?

1. 콜백 함수의 정의

  • 콜백 함수는 다른 코드의 인자로 넘겨주는 함수입니다. 즉, 콜백 함수는 함수나 메서드가 필요할 때 호출할 수 있도록, 다른 함수에 전달됩니다. JavaScript에서는 setTimeout, forEach와 같은 함수가 콜백 함수를 받아들이는 대표적인 예입니다.
// setTimeout
setTimeout(function() {
  console.log("Hello, world!");
}, 1000);

// forEach
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(number) {
  console.log(number);
});

 

2. 콜백 함수의 제어권

  • 콜백 함수를 넘겨받은 코드는 언제, 어떻게 콜백 함수를 호출할지에 대한 제어권을 가집니다. 즉, 호출 시점과 방식은 콜백 함수를 사용하는 코드(forEach, setTimeout 등)에 의해 결정됩니다.
var count = 0;
var timer = setInterval(function() {
  console.log(count);
  if (++count > 4) clearInterval(timer);
}, 300);
  • 위 코드에서 setInterval은 콜백 함수가 0.3초마다 호출되도록 제어권을 가지고 있습니다.

 

3. 콜백 함수와 인자

  • 콜백 함수의 인자는 호출되는 함수의 규칙에 따라 전달됩니다. 예를 들어, Array.prototype.map 함수는 콜백 함수에 배열의 요소와 해당 요소의 인덱스를 인자로 넘깁니다.
  • var newArr = [10, 20, 30].map(function(currentValue, index) {
      console.log(currentValue, index);
      return currentValue + 5;
    });
    console.log(newArr);
    
    // -- 실행 결과 --
    // 10 0
    // 20 1
    // 30 2
    // [15, 25, 35]
  • 콜백 함수의 인자 순서를 바꾸면 예상치 못한 결과가 발생할 수 있습니다.
  • var newArr2 = [10, 20, 30].map(function(index, currentValue) {
      console.log(index, currentValue);
      return currentValue + 5;
    });
    console.log(newArr2);
    
    // -- 실행 결과 --
    // 10 0
    // 20 1
    // 30 2
    // [5, 6, 7]
  • 이처럼 콜백 함수의 인자는 정의된 규칙에 맞게 작성해야 합니다.

 

4. 콜백 함수와 this

  • 콜백 함수도 일반 함수와 마찬가지로 기본적으로 this는 전역 객체를 참조합니다. 그러나 콜백 함수에 this를 명시적으로 지정할 수 있습니다.
Array.prototype.mapaaa = function(callback, thisArg) {
  var mappedArr = [];
  for (var i = 0; i < this.length; i++) {
    var mappedValue = callback.call(thisArg || globalThis, this[i]);
    mappedArr[i] = mappedValue;
  }
  return mappedArr;
};

const a = [1, 2, 3].mapaaa(function(item) {
  return item * 2;
});

console.log(a); // [2, 4, 6]

 

  • call 메서드를 사용해 this를 명시적으로 지정할 수 있습니다. 이를 통해 제어권을 넘겨받는 코드에서 콜백 함수의 this를 원하는 대로 설정할 수 있습니다.
// setTimeout은 기본적으로 전역 객체를 참조합니다.
setTimeout(function() {
  console.log(this); // Window { ... }
}, 300);

// forEach도 마찬가지로 전역 객체를 참조합니다.
[1, 2, 3, 4, 5].forEach(function(x) {
  console.log(this); // Window { ... }
});

// addEventListener는 this를 이벤트 대상 객체로 설정합니다.
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
  console.log(this, e); // <button id="a">클릭</button> MouseEvent
});