파라미터로 함수를 전달하는 함수
콜백함수
란 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다.
let number = [1, 2, 3, 4, 5];
number.forEach(x => {
console.log(x * 2);
});
<output>
2
4
6
8
10
콜백함수는 이미 우리의 코드 속에서 자주 사용되고 있다.
예를 들어, forEach 함수의 경우 함수 안에 익명의 함수를 넣어서 forEach 문을 동작시킨다.
let number = [1, 2, 3, 4, 5];
number.forEach(function(x) {
console.log(x * 2);
});
위의 예제를 화살표 함수에서 일반 함수로 바꾼 예제이다.
콜백함수는 이름이 없는 익명의 함수를 사용한다.
함수의 내부에서 실행되기 때문에 이름을 붙이지 않아도 된다.
function whatYourName(name, callback) {
console.log('name: ', name);
callback();
}
function finishFunc() {
console.log('finish function');
}
whatYourName('miniddo', finishFunc);
<output>
name: miniddo
finish function
✨ TIP ✨
JavaScript Data Type
- number, string, boolean, object(function, array, data, regexp), null, undefined
전역변수(Global Variable) : 함수 외부에서 선언된 변수
ex) let fruit = 'apple'; // Global Variable
지역변수(Local Variable) : 함수 내부에서 선언된 변수
function callbackFunc(callback) {
let vegetable = 'tomato'; // Local Variable
callback(vegetable);
}
function eat(vegetable) {
console.log(`fruit: ${fruit} / vegetable: ${vegetable}`);
}
callbackFunc(eat);
<output>
fruit: apple / vegetable: tomato
let userData = {
signUp: '2022-05-16 15:00:00',
id: 'dnjsp',
name: 'Not Set',
setName: function(firstName, lastName) {
this.name = firstName + ' ' + lastName;
}
}
function getUserName(firstName, lastName, callback) {
callback(firstName, lastName);
}
getUserName('JO', 'WONHYE', userData.setName);
console.log('1: ', userData.name);
console.log('2: ', window.name);
<output>
1: Not Set
2: JO WONHYE
첫번째 콘솔에서 JO WONHYE
가 출력되길 원했지만, Not Set이 출력된다.
setName()
함수가 실행되기 전의 name 값이 나오는데, 이는 getUserName()
이 전역 함수이기 때문이다.
즉, setName()
에서 사용된 this
객체가 window
라는 글로벌 객체를 가리킨다.
따라서 this
를 보호할 수 있는 콜백함수를 만들어야 한다.
해결 방안:
call()
과apply()
를 사용하여this
를 보호할 수 있다.
call()
: 첫 번째 인자로 this
객체 사용, 나머지 인자들은 ,
로 구분apply()
: 첫 번째 인자로 this
객체 사용, 나머지 인자들은 배열 형태로 전달// call
let userData = {
signUp: '2022-05-16 15:00:00',
id: 'dnjsp',
name: 'Not Set',
setName: function(firstName, lastName) {
this.name = firstName + ' ' + lastName;
}
}
function getUserName(firstName, lastName, callback, obj) {
callback.call(obj, firstName, lastName); (1)
}
getUserName('JO', 'WONHYE', userData.setName, userData); (2)
console.log(userData.name);
// JO WONHYE
(2)에서 마지막 인자에 담긴 userData
는 (1)에서 call
함수의 첫번째 인자로 전달된다.
즉, call()
에 의해서 userData
에 this
객체가 매핑된다.
비동기 호출이 자주 일어나는 프로그램의 경우 '콜백 지옥'이 발생한다.
함수의 매개변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들어질 정도로 깊어지는 현상이다.
function add(x, callback) {
let sum = x + x;
console.log(sum);
callback(sum);
}
add(2, function(result) {
add(result, function(result) {
add(result, function(result) {
console.log('finish!!');
})
})
})
/*
4
8
16
finish!!
*/
해결방안:
Promise
를 사용하여 콜백지옥을 탈출한다.