this는 함수를 실행할 때 그 실행 context를 설명하는 현재 실행 문맥이다. this는 크게 아래와 같이 다섯가지의 종류로 구분할 수 있다.
첫 번째와 두 번째는 유사한 개념이므로 같이 묶도록 하겠다. 전역 스코프와 function 호출 상황일 때인데 전역 스코프에 함수를 정의한 후 this를 호출하면 this는 window라는 전역 스코프에 가리키게 된다. 전역 스코프에 this는 웹브라우저의 window이고 함수 실행에서의 실행 문맥도 전역 객체이다.
// 전역에서의 this
console.log(this); // Window {...}
// 전역 스코프 함수에서의 this
function foo() { console.log(this); } // Window {...}
객체의 프로퍼티로 있는 Method 호출 시 객체에 속한 this 는 그 속해 있는 부모 object 를 가리킨다.
const obj = {
a: function() {
console.log(this);
} // {a: ƒ}
생성자 함수 실행 시 표현식 앞에 new라는 키워드가 붙어 함수 객체로 계산되어 수행되는데 여기서 this는 새로 만들어지는 인스턴스(me)를 가리킨다.
function Person(name) {
this.name = name;
}
const me = new Person('Jo');
bind(), call(), apply()를 호출할 때 this는 첫번째 인자로 명시된 객체를 가리킨다.
const obj2 = {
b: 'b'
};
function foo2() {
console.log(this);
}
foo2.bind(obj2).call(); // {b: "b"}
foo2.call(obj2); // {b: "b"}
foo2.apply(obj2); // {b: "b"}
추가적으로 함수를 호출할 때, 함수가 객체의 메소드인지 보통의 함수인지에 따라 this가 가리키는 대상이 달라진다.
obj3.c()를 호출하면 객체의 메소드이기 때문에 obj3를 가리키게 된다. 하지만 obj3.c를 foo3에 할당하여 foo3를 호출하면 foo3()를 객체의 메소드를 참조하는 것이 아니라 보통의 함수인 'function() { console.log(this); }' 를 참조하고 있으므로 this는 Window 객체를 가리키게 된다.
const obj3 = {
c: function() {
console.log(this);
}
};
obj3.c(); // {c: ƒ}
const foo3 = obj3.c;
foo3(); // Window {...}