Index
객체지향 프로그래밍에서 자신이 속한 객체의 프로퍼티를 참조하고 변경하는 것은 매우 중요합니다.
이는 객체의 상태(state)를 관리하고, 행동(behavior)과 데이터(data)를 결합하는 객제치향프로그래밍의 핵심 개념 중 하나이다.
1. this의 존재 당위성
🧐 Q. 객체 리터럴 방식으로 생성한 객체의 경우 메서드 내부에서 메서드 자신이 속한 객체를 가리키는 식별자를 재귀적으로 참조할 경우 어떠한 문제가 발생될까?
const circle = {
radius: 5,
getDiameter() {
return 2 * circle.radius;
},
};
// (1) 의도한 동작
console.log(circle.getDiameter()); // 10
// (2) 문제 상황
const anotehrCircle = circle;
anotherCircle.radius = 10;
console.log(anotherCircle.getDiameter()); // 20
// (3) 객체 참조 변경
const detachedMethod = circle.getDiameter;
console.log(detachedMethod()); // TypeError 또는 10 (의도치 않은 결과)
1.1 객체 이름에 의존
- 메서드 내부에서
circle
을 직접 참조하면, 해당 메서드는 항상 특정 이름(circle
)에 묶여 동작합니다. - 객체를 복사하거나 다른 변수에 할당하면 참조가 깨지거나 의도치 않은 동작이 발생합니다.
1.2 재사용성 저하
- 메서드를 다른 객체로 재사용하거나, 메서드만 별도로 호출하려는 경우 문제가 발생합니다.
this
를 사용하지 않으면 메서드가 객체 독립적으로 동작하지 못합니다.
🧐 Q. 생성자 함수를 정의하는 시점에는 아직 인스턴스가 생성되기 이전이므로 인스턴스를 가르키는 식별자는 어떻게 알 수 있을까?
// (4) 인스턴스 생성의 전제, 생성자함수의 존재
function Circle(radius) {
????.radius = radius;
}
Circle.prototype.getDiameter = function() {
return 2 * ????.radius;
};
const circle = new Circle(5);
1.3 자기 참조 변수 필요
- 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없기 때문에 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요하다. 이를 위해 자바스크립트는
this
라는 특수한 식별자를 제공한다.
2. 함수 호출 방식과 this 바인딩
// (1) 전역에서 this는 전역객체 window를 가리킨다.
console.log(this); // window
-----------------------------------------------------------------------------------------
// (2) 일반 함수 내부에서 this는 전역객체 window를 가리킨다.
function square(number) {
console.log(this); // window
return number * number;
}
square(2);
-----------------------------------------------------------------------------------------
// (3) 메서드 내부에서 this는 메서드를 호출한 객체를 가리킨다.
const person = {
name: 'Lee',
getName() {
console.log(this); // {name: "Lee", getNameL f}
return this.name;
}
};
console.log(person.getName());
-----------------------------------------------------------------------------------------
// (4) 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
function Person(name) {
this.name = name;
console.log(this); // Person {name: 'Lee'}
}
const me = new Person('Lee');
-----------------------------------------------------------------------------------------
// (5) Function.prototype.apply/call/bind 메서드에 의한 호출
function getThisBinding() {
return this;
}
const thisArg = { a: 1};
console.log(getThisBinding()); // window
// getThisBinding 함수를 호출하면서 인수로 전달할 객체를 getThisBinding 함수의 this에 바인딩한다.
console.log(getThisBinding.apply(thisArg)); // {a: 1}
console.log(getThisBinding.call(thisArg); // {a: 1}
// Function.prototype.bind 메서드는 apply와 call메서드와 달리 함수를 호출하지 않는다. 다만 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환한다.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
console.log(getThisBinding.bind(thisArg)()); // {a: 1}

Property of this binding
Ungmo Lee. (2020). Modern Javascript DeepDive. wikibooks. p.358.