자바스크립트 this, 7개의 예제로 이해해버리기!
- 언어/Javasript
- 2019. 7. 30. 12:17
자바스크립트의 this는 '호출자', 실행 문맥' 을 가리킵니다. 7개의 예제를 통해서 this를 뽀개보도록 하겠습니다.
예제 1.
console.log(this === window);
그냥 this를 호출하면 이는 window 객체가 됩니다.
예제 2.
function test1() {
console.log(this === window);
}
test1();
함수에서도 this를 호출하면 window 객체입니다.
예제 3.
function test1() {
'use strict'
console.log(this === undefined);
}
test1();
strict 모드의 함수에서는 this가 undefined 입니다.
예제 4.
function test1() {
'use strict'
function test1_inner() {
console.log(this === undefined)
}
test1_inner();
}
test1();
strict 모드일 경우 내부 scope에서도 this 는 undefined로 동일하게 적용됩니다.
예제 5.
var person = {
name: 'NoDoudt',
age: 30,
introduce: function() {
console.log(this === person);
function fake_age() {
console.log(this === window);
return this.age - 5;
}
return ''.concat('내 이름은 ', this.name, ', 나이는 ', fake_age(), '이죠');
}
}
person.introduce();
// 내 이름은 NoDoudt, 나이는 NaN이죠.
fake_age() 안에 있는 this는 객체 내부에서의 this라 person 객체를 가르킨다고 생각하기 쉽지요. 하지만 window를 가르킵니다.
우리가 생각하는 대로 this가 person 객체를 가르키도록 하려면 아래와 같이 해야 합니다.
var person = {
name: 'NoDoudt',
age: 30,
introduce: function() {
console.log(this === person);
function fake_age() {
console.log(this === person);
return this.age - 5;
}
return ''.concat('내 이름은 ', this.name, ', 나이는 ', fake_age.call(this), '이죠');
}
}
person.introduce();
// 내 이름은 NoDoudt, 나이는 25이죠.
예제 6.
function Person(name, age) {
console.log(this instanceof Person); // Person 타입임을 확인
this.name = name;
this.age = age;
}
Person.prototype.introduce = function() {
console.log(this instanceof Person); // Person 타입임을 확인
return ''.concat('내 이름은 ', this.name, ', 나이는 ', this.age, '이죠');
}
var p1 = new Person('NoDoudt', 30);
p1.introduce();
// 내 이름은 NoDoudt, 나이는 30이죠.
class Person {
constructor(name, age) {
console.log(this instanceof Person); // Person 타입임을 확인
this.name = name;
this.age = age;
}
introduce() {
console.log(this instanceof Person); // Person 타입임을 확인
return ''.concat('내 이름은 ', this.name, ', 나이는 ', this.age, '이죠');
}
}
var p1 = new Person('NoDoudt', 30);
p1.introduce();
// 내 이름은 NoDoudt, 나이는 30이죠.
생성자에서의 this는 새롭게 만들어진 객체를 나타냅니다.
예제 7.
function Person(name, age, nickname) {
console.log(this instanceof Person); // Person 타입임을 확인
this.name = name;
this.age = age;
this.nickname = nickname;
}
Person.prototype.introduce = function() {
console.log(this instanceof Person); // Person 타입임을 확인
this.nickname.map(function(value, index) {
console.log(this === window); // this는 window.
console.log(''.concat('내 이름은 ', this.name, '(', this.age,'). ', '근데 친구들이 ', value, '라고 자꾸 놀려..ㅠㅠ'));
});
}
var p1 = new Person('NoDoudt', 30, ['바보', '머저리', '센쩍하는 양아치']);
p1.introduce();
// 내 이름은 (undefined). 근데 친구들이 바보라고 자꾸 놀려..ㅠㅠ
// 내 이름은 (undefined). 근데 친구들이 머저리라고 자꾸 놀려..ㅠㅠ
// 내 이름은 (undefined). 근데 친구들이 센쩍하는 양아치라고 자꾸 놀려..ㅠㅠ
map 안에서 this는 non-strict 모드에서 window이고, strict 모드에선 undefined 입니다. 위 예에선 this가 window 이기 때문에 this.name은 undefined가 나왔네요.
우리가 생각한 대로 동작하도록 고치려면,
(1) map 의 파라미터로 들어가는 함수에 bind(this)를 추가로 호출해주는 것입니다.
...
console.log(this instanceof Person); // Person 타입임을 확인
this.nickname.map(function(value, index) {
console.log(this instanceof Person); // Person 타입임을 확인
console.log(''.concat('내 이름은 ', this.name, '(', this.age,'). ', '근데 친구들이 ', value, '라고 자꾸 놀려..ㅠㅠ'));
}.bind(this) );
...
var p1 = new Person('NoDoudt', 30, ['바보', '머저리', '센쩍하는 양아치']);
p1.introduce();
// 내 이름은 NoDoudt(30). 근데 친구들이 바보라고 자꾸 놀려..ㅠㅠ
// 내 이름은 NoDoudt(30). 근데 친구들이 머저리라고 자꾸 놀려..ㅠㅠ
// 내 이름은 NoDoudt(30). 근데 친구들이 센쩍하는 양아치라고 자꾸 놀려..ㅠㅠ
(2) map 함수에 array function을 사용하는 것입니다.
...
console.log(this instanceof Person); // Person 타입임을 확인
this.nickname.map((value, index) => {
console.log(this instanceof Person); // Person 타입임을 확인
console.log(''.concat('내 이름은 ', this.name, '(', this.age,'). ', '근데 친구들이 ', value, '라고 자꾸 놀려..ㅠㅠ'));
});
...
var p1 = new Person('NoDoudt', 30, ['바보', '머저리', '센쩍하는 양아치']);
p1.introduce();
// 내 이름은 NoDoudt(30). 근데 친구들이 바보라고 자꾸 놀려..ㅠㅠ
// 내 이름은 NoDoudt(30). 근데 친구들이 머저리라고 자꾸 놀려..ㅠㅠ
// 내 이름은 NoDoudt(30). 근데 친구들이 센쩍하는 양아치라고 자꾸 놀려..ㅠㅠ