자바스크립트에서 this
는 호출되는 방식에 따라 달라지기 때문에 이해하기 너무 어려운 관계로 아예 대표적인 몇 가지를 그냥 외워버리기로 함.
1. 자유함수 호출
가장 기본적인 경우, 별다른 조건이 없을 때에 this는 전역객체를 바라본다.
1
2
3
4
5
6
7
| console.log(this === window); // true
console.log(toString.call(this)); // [object Window]
function freeFunction() {
console.log(this === window); // true
}
freeFunction();
|
browser의 전역객체는 window
node의 전역객체는 global
2. 생성자 호출
new 키워드를 이용한 생성자 호출시에 함수 내부 this는 새로운 객체를 바라본다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| function NewFunction() {
this.name = "이름";
console.log(this); // NewFunction
console.log(toString.call(this)); // [object Object]
console.log(this.name); // 이름
}
/* 생성자 호출 */
let fun = new NewFunction();
console.log(fun.name); // 이름
/* 일반함수 호출 */
let fun2 = NewFunction();
console.log(fun2.name); // Uncaught TypeError: Cannot read property 'name' of undefined
|
3. Object의 Method 호출
Object의 Method를 호출했을 때엔 this는 Object를 가리킨다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| let car = {
name: "myCar",
color: "red",
/* Method */
getName: function () {
console.log(this); // car {name: 'myColor', color: 'red', getName () ... }
console.log(this.name); // myCar
},
/* Method 축약형 */
getColor() {
console.log(this); // car {name: 'myColor', color: 'red', getName () ... }
console.log(this.color); // red
},
/* arrow function의 경우 다른 규칙이 적용된다. 4번 참고 */
getArrow: () => {
console.log(this); // Window
console.log(this.name); // undefined
console.log(this.color); // undefined
},
};
car.getColor();
car.getName();
car.getArrow();
|
4. Arrow Function 호출
ES6에서 추가된 Arrow Function의 경우, 생성된 시점의 주변 스코프의 this를 갖게된다
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
| let office = {
pencil: 4,
getArrow: () => {
/*
getArrow가 생성될 때의 주변 스코프인 office 객체,
office 객체의 this는 Window객체이므로 getArrow의 this는 Window를 바라본다
*/
console.log(this); // Window
console.log(this.pencil); // undefined
},
getPencil() {
/* getPencil은 일반적인 method이므로 위의 3번 규칙을 따라 this는 office 객체를 바라본다 */
console.log(this.pencil); // 4
let getPpencilFun = function () {
/* 1번규칙인 일반 함수 호출에 의해 Window를 바라본다 */
console.log(this.pencil); // undefined
};
getPpencilFun();
let getPencilArrow = () => {
/*
getPencilArrow arrow function 규칙에 의해
getPencil method가 생성될 때의 this인 office 객체를 바라본다
*/
console.log(this.pencil); // 4
};
getPencilArrow();
},
};
office.getArrow();
office.getPencil();
|
5. call, apply, bind로 함수 호출
각각 함수를 호출하고, 정의하는 Function의 메소드이다. 첫번째 인자를 통해 this를 변경할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| let office = {
paper: 100,
getPaper() {
console.log(this.paper);
},
};
let home = {
paper: 10,
};
office.getPaper(); // 100: 일반함수 메소드 호출
office.getPaper.call(home); // 10: 해당함수의 this를 home객체로 변경
office.getPaper.call(this); // undefined: this가 Window로 변경
office.getPaper.call(null); // undefined: this가 지정이 안되어 있으므로, 기본 함수의 this인 Window를 봄
office.getPaper.call(); // undefined: 상동
office.getPaper.apply(home); // 10: 해당함수의 this를 home객체로 변경
let bind = office.getPaper.bind(home);
bind(); // 10
|