객체는 상태를 나타내는 프로퍼티와 동작을 나타내는 메서드를 하나의 논리적인 단위로 묶은 복합적인 자료구조
동작을 나타내는 메서드는 자신이 속한 객체의 상태, 즉 프로퍼티를 참조하고 변경할 수 있어야 한다.
이 때 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
자바나 C++ 같은 클래스 기반 언어에서 this는 언제나 클래스를 생성하는 인스턴스를 가리킨다.
하지만 자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.
함수를 호출하는 방식
일반 함수 호출
메서드 호출
생성자 함수 호출
Function.prototype.apply/call/bind 메서드에 의한 간접 호출
기본적으로 this는 전역 객체가 바인딩 된다.
function foo(){
console.log("foo's this: ", this); // window
function bar(){
console.log("bar's this: ", this); // window
}
bar()
}
foo();
일반 함수로 호출하면 함수 내부의 this에는 전역 객체가 바인딩된다.
객체를 생성하지 않는 일반 함수에서 this는 의미가 없다
strict mode가 적용된 일반 함수 내부의 this에는 undefined가 바인딩된다.
메서드 내에서 정의한 중첩함수 또는 메서드에게 전달한 콜백함수가 일반 함수로 호출될 때 this가 전역 객체를 바인딩한다.
→ 이것은 문제가 있다.
var value = 1;
const obj = {
value: 100,
foo(){
console.log("foo's this: ", this); // {value: 100, foo: f}
setTimeout(function (){
console.log(this); // **window**
console.log(this.value); // 1
}, 100);
}
}
메서드 내부의 중첩 함수나 콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키기 위한 방법은 다음과 같다.
1번째 방법
var value = 1;
const obj = {
value: 100,
foo(){
const that = this;
setTimeout(function (){
console.log(that.value); // 100
}, 100);
}
}
2번째 방법 (Function.prototpye.bind)
var value = 1;
const obj = {
value: 100,
foo(){
setTimeout(function (){
console.log(this.value); // 100
}.bind(this), 100);
}
}
3번째 방법 (화살표 함수)
var value = 1;
const obj = {
value: 100,
foo(){
setTimeout(()=>{
console.log(this.value); // 100
}, 100);
}
}
메서드를 호출한 객체가 this 바인딩
생성자 함수가 (미래에) 생성할 인스턴스가 this 바인딩
Function.prototype.apply/call/bind 메서드에 첫번째 인수로 전달한 객체가 this 바인딩