JS this 키워드
배경
객체는 상태(state)를 나타내는 프로퍼티와 동작(behavior)을 나타내는 메서드를 하나의 논리적인 단위로 묶은 복합적인 자료구조다.
메서드는 프로퍼티를 참조하고 변경할 수 있어야 한다. 이때 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
그런데 생성자 함수 방식으로 인스턴스를 생성하는 경우를 생각해보면 먼저 생성자 함수가 존재해야 한다.
function Circle(radius) {
// 이 시점에서 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
??.radius = radius;
}
Circle.prototype.getDiameter = function() {
// 이 시점에서 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
return 2 * ??.radius;
}
const circle = new Circle(5);
생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없다. 따라서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요하다. 이를 위해 JS는 this
식별자를 제공한다.
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getDiameter = function () {
return 2 * this.radius;
};
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10
this
바인딩
this
바인딩(this에 바인딩될 값)은 함수 호출 방식, 즉 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다.
const foo = function () {
console.dir(this);
};
// 1. 일반 함수 호출
foo(); // window
// 2. 메서드 호출 : foo 함수를 프로퍼티 값으로 할당하여 호출
const obj = { foo };
obj.foo(); // obj
// 사용법
const Circle = {
radius: 5,
getDiameter() {
return 2 * this.radius;
},
};
// 3. 생성자 함수 호출 : foo 함수를 new 연산자와 함께 생성자 함수로 호출
new foo(); // foo {}
// 사용법
function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle = new Circle(5);
// 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
const bar = { name: "bar" }; // this로 사용할 객체
foo.call(bar); // bar
foo.apply(bar); //bar
foo.bind(bar)(); // bar
정리
함수 호출 방식 | this 바인딩 |
---|---|
일반 함수 호출 | 전역 객체 |
메서드 호출 | 메서드를 호출한 객체 |
생성자 함수 호출 | 생성자 함수가 (미래에) 생성할 인스턴스 |
Function.prototype.apply/call/bind 메서드에 의한 간접 호출 | Function.prototype.apply/call/bind 메서드에 첫 번째 인수로 전달한 객체 |
출처 :
- 모던 자바스크립트 Deep Dive 342p - 22 this
댓글남기기