이처럼 단순히 함수의 파라미터에 함수를 넘겨주면 끝이라 생각하기 쉽지만 자바스크립트의 콜백 함수 이용에는 몇가지 조심해야 할 주의점이 있습니다.
다음을 보겠습니다. 함수에서 this는 무엇일까요?
|
function fn1() {
console.log(`선억적 함수 this : ${this}`);
console.log(this);
}
let fn2 = () => {
console.log(`화살표 함수 this : ${this}`);
console.log(this);
}
// 함수에서 this는 기본적으로 전역객체의 window로 정해져 있습니다.
fn1();
fn2();
|
실행 결과를 보면 다음과 같이 window객체를 나타냅니다.

그렇다면 전달되는 콜백함수가 this를 사용하고 있다면 문제가 생깁니다.
다음을 보겠습니다.
|
let user = {
signUp: '2024-08-31',
name: '무명',
age : 22,
setName: function (name) { // 메서드 선언
this.name = name;
},
setSignUp: function (signUp) { // 메서드 선언
this.signUp = signUp;
},
setAge(age){ // 메서드 축약형
this.age = age;
},
show(){ // 메서드 축약형
return `${this.name}씨(가입일 : ${this.signUp}, ${this.age}세)`;
}
}
console.log(user.show());
function setName(name, callback){
callback(name);
}
function setSignUp(signUp, callback){
callback(signUp);
}
function setAge(age, callback){
callback(age);
}
setName('한사람', user.setName);
setSignUp('2024-10-01', user.setSignUp);
setAge(33, user.setAge);
console.log(user.show());
// 왜 바뀌지 않았을까?
console.log(`user.name = ${user.name}`);
console.log(`user.name = ${user.signUp}`);
// 콜백함수에서 this는 전역 객체이다.
console.log(`window.name = ${window.name}`);
console.log(`window.name = ${window.signUp}`);
|
결과입니다. 에러는 아니지만 원하는 값은 변경되지 않았습니다.

이 문제를 해결하려면 어떻게 해야 할까요? 함수를 다음과 같이 변경해 줘야 합니다.
|
// 이것을 해결하여면 다음과 같이 해야 한다.
function setName(name, callback, data){
callback.call(data, name);
}
function setSignUp(signUp, callback, data){
callback.apply(data, [signUp]);
}
function setAge(age, callback, data){
callback.bind(data)(age);
}
setName('이세상', user.setName, user);
setSignUp('2024-11-01', user.setSignUp, user);
setAge(44, user.setAge, user);
console.log(user.show());
|
다음과 같이 user객체의 내용이 변경되었습니다.

콜백 함수 this 해결 방안
따라서 콜백 함수 내의 this를 보호할 수 있도록 콜백 함수를 만들어야 합니다.
해결 방안으로는 call() 과 apply() 그리고 bind()를 사용하여 this 를 보호할 수 있습니다.
call() : 첫 번째 인자로 this 객체 사용, 나머지 인자들은 , 로 구분해서 전달합니다.
apply() : 첫 번째 인자로 this 객체 사용, 나머지 인자들은 배열 형태로 전달 합니다.
bind() : 함수가 가리키는 this만 바꾸고 호출하지는 않는 겁니다. 정확히 말하면 this를 정의하고 나서 그 함수를 복사해 새로운 함수를 만들어 리턴 하는 겁니다.
해결방법은 콜백 함수 내에서 call(), apply(), bind() 메서드를 통해 콜백 함수가 참조할 객체를 지정해주면 됩니다.
|
function 함수(변경값, callback함수, 변경객체){
callback함수.call(변경객체, 변경할 값);
또는 callback함수.apply(변경객체, [변경할 값]);
}또는 callback함수.bind(변경객체)(변경할 값); |
ex05.html 파일을 다음과 같이 만듭니다.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>콜백함수 내의 this 문제점</title>
<script>
let user = {
signUp: '2024-08-31',
name: '무명',
age : 22,
setName: function (name) { // 메서드 선언
this.name = name;
},
setSignUp: function (signUp) { // 메서드 선언
this.signUp = signUp;
},
setAge(age){ // 메서드 축약형
this.age = age;
},
show(){ // 메서드 축약형
return `${this.name}씨(가입일 : ${this.signUp}, ${this.age}세)`;
}
}
console.log(user.show());
function setName(name, callback){
callback(name);
}
function setSignUp(signUp, callback){
callback(signUp);
}
function setAge(age, callback){
callback(age);
}
setName('한사람', user.setName);
setSignUp('2024-10-01', user.setSignUp);
setAge(33, user.setAge);
console.log(user.show());
// 왜 바뀌지 않았을까?
console.log(`user.name = ${user.name}`);
console.log(`user.name = ${user.signUp}`);
// 콜백함수에서 this는 전역 객체이다.
console.log(`window.name = ${window.name}`);
console.log(`window.name = ${window.signUp}`);
// 이것을 해결하여면 다음과 같이 해야 한다.
function setName(name, callback, data){
callback.call(data, name);
}
function setSignUp(signUp, callback, data){
callback.apply(data, [signUp]);
}
function setAge(age, callback, data){
callback.bind(data)(age);
}
setName('이세상', user.setName, user);
setSignUp('2024-11-01', user.setSignUp, user);
setAge(44, user.setAge, user);
console.log(user.show());
</script>
</head>
<body>
<div id="result"></div>
</body>
</html>
|
cs |
실행 결과 입니다.

'Front End > Javascript' 카테고리의 다른 글
| [JavaScript] call() & apply() & bind()의 사용 2 (0) | 2024.10.24 |
|---|---|
| [JavaScript] call() & apply() & bind()의 사용 (0) | 2024.10.24 |
| [JavaScript] 콜백(Callback) 함수 4(활용 사례) (1) | 2024.10.24 |
| [JavaScript] 콜백(Callback) 함수 3(인사하기) (0) | 2024.10.24 |
| [JavaScript] 콜백(Callback) 함수 2(계산기) (0) | 2024.10.24 |