What is this?
05 June, 2020 - JavaScript - 3 min read
this
는 호출하는 방식에 따라 달라지며, 크게 다섯 가지 경우로 나눌 수 있다.
1. 전역에서 this는 언제나 window
console.log(this); // Window
console.log(this === window); // true
2. 일반 함수 호출은 언제나 window
function normalFunc1() {
console.log(this);
}
normalFunc1(); // Window
function normalFunc2() {
function innerFunc() {
console.log(this);
}
innerFunc();
}
normalFunc2(); // Window
// 메소드 내부의 일반 함수에서도 window
// 그러나 화살표 함수는 자동으로 외부 환경에 바인딩 되어 외부 환경이 this로 나온다.
const obj = {
method: function() {
function innerFunc() {
console.log(this);
}
innerFunc();
},
secondMethod: function() {
const arrowFunc = () => {
console.log(this);
}
arrowFunc();
}
}
obj.method(); // Window
obj.secondMethod(); // {e: ƒ, g: ƒ}
3. 메소드 호출에서의 this는 .(점) 앞에 있는 것. 즉, 메소드가 담긴 객체
const obj = {
prop: 'Hello world',
method: function() {
console.log(this.prop);
}
}
obj.method(); // Hello world
그러나 메소드 내부함수의 경우는 또 얘기가 달라진다. 이때는 일반 함수에서의 this와 마찬가지로 전역을 가리킨다.
var prop = 'This is window';
const obj = {
prop: 'Bye world',
method: function() {
console.log(this.prop);
function innerFunc() {
console.log(this.prop);
}
innerFunc();
}
}
obj.method(); // Bye world
// This is window
위와 같은 문제에 대처하기 위한 방법으로 this를 변수에 할당하는 우회법이 있다. 그리고, 내부함수를 화살표 함수로 작성하면 외부환경인 메소드의 this를 그대로 바인딩한다.
const obj = {
prop: 'Nice to meet you world',
method: function() {
// this를 that에 할당
const that = this;
function innerFunc() {
console.log(that.prop);
}
innerFunc();
},
secondMethod: function() {
const innerArrow = () => {
console.log(this.prop);
}
innerArrow();
}
}
obj.method(); // Nice to meet you world
obj.secondMethod(); // Nice to meet you world
4. 콜백에서의 this는 기본적으로는 일반 함수처럼 전역을 가리킨다
const obj = {
prop: 'This is callback',
method: function() {
setTimeout(() => {
console.log(this.prop);
}, 1000);
},
secondMethod: function() {
setTimeout(function() {
console.log(this.prop);
}.bind(obj), 1000); // <- binding
}
}
// 화살표 함수로 작성하면 외부 환경에 바인딩
obj.method(); // This is callback
obj.secondMethod(); // This is callback
하지만, call, apply, bind 메서드를 통해 this를 명시적으로 바인딩 할 수 있다.
function a(x, y, z) {
console.log(this, x, y, z);
}
var b = {
c: 'Hello'
};
a.call(b, 1, 2, 3); // {c: "Hello"} 1 2 3
a.apply(b, [1, 2, 3]); // {c: "Hello"} 1 2 3
var c = a.bind(b);
c(1, 2, 3); // {c: "Hello"} 1 2 3
var d = a.bind(b, 1, 2);
d(3); // {c: "Hello"} 1 2 3
5. 생성자 함수에서의 this는 instance
class Animal {
constructor(name, species) {
this.name = name;
this.species = species;
}
}
Animal.prototype.whatIsThis = function() {
console.log(this);
};
const dog = new Animal('Max', 'Dog');
dog.whatIsThis(); // Animal {name: "Max", species: "Dog"}
const cat = new Animal('Alice', 'Cat');
cat.whatIsThis(); // Animal {name: "Alice", species: "Cat"}
참고: