프로토타입 메서드와 this 바인딩
* 우선 먼저 간단한 용어의 정의를 짚고 넘어가겠습니다. '프로토타입 메서드'는 우리가 어떤 객체의 프로토타입 객체의 프로퍼티 중 하나로 선언한 메서드를 의미합니다.
프로토타입 메서드 형태로 정의한 메서드 내부에서 this를 사용했을 경우에는, 이 this는 어디에 바인딩될까요? 사실 프로토타입에서 선언한 메서드라고 해서 특별한 별도의 this 바인딩 규칙을 갖거나 하지는 않습니다. 우리가 지난 아티클에서 배웠던 this 바인딩 법칙을 그대로 적용해도 큰 무리가 없습니다.
그럼 하나 다시 복습해 보겠습니다. 프로토타입 '메서드'라는 표현에서 알 수 있듯이, 이 함수는 프로토타입 객체의 속성으로서 선언된 메서드입니다. 우리는 메서드에서 사용한 this 키워드가 어떤 패턴으로 바인딩되는지 배웠습니다. 기억나시나요? 바로 [메서드에서 사용한 this는 호출한 객체와 바인딩 된다] 였습니다. 복잡해 보여도 이 원칙을 벗어나지 않는다는 점을 잘 기억하고, 아래 예제 코드를 살펴보겠습니다.
// 생성자 함수
function Rapper(rapName) {
this.rapName = rapName;
}
// 프로토타입 메서드 getRapName() 선언
Rapper.prototype.getRapName = function() {
return this.rapName;
}
var swings = new Rapper('MOON SWINGS');
console.log(swings.getRapName());
// 출력
// MOON SWINGS
위의 예제에서 getRapName( )이라는 프로토타입 메서드를 선언했고, this.rapName을 리턴하도록 선언했습니다. 반복적이지만, 프로토타입 메서드의 동작 순서를 다시 한번 짚어보겠습니다. getRapName( )이라는 메서드는 Rapper의 프로토타입 메서드로 선언되었기 때문에 Rapper.prototype을 [[Prototype]] 링크로 연결하는 객체들, 즉 Rapper의 자식 객체들도 사용할 수 있는 메서드입니다.
이에 따라 Rapper 생성자를 통해 swings라는 객체를 생성했습니다. 그리고 swings.getRapName( )을 실행했죠. '메서드'이기 때문에, 해당 메서드의 this는 자신을 호출한 객체 즉 swings에 바인딩되었습니다. 그래서 swings.rapName인 'MOOD SWINGS'가 리턴되어 출력되었습니다.
프로토타입 메서드라고 해서 특별한 작동 프로세스가 있는 것이 아니라는 점을 확인했습니다. '메서드이므로 자신을 호출한 객체와 this 바인딩이 일어난다'는 원칙만 잘 기억하면 됩니다. 그럼 위의 코드에 약간의 응용을 더해보도록 하겠습니다.
// 생성자 함수
function Rapper(rapName) {
this.rapName = rapName;
}
// 프로토타입 메서드 getRapName() 선언
Rapper.prototype.getRapName = function() {
return this.rapName;
}
var swings = new Rapper('MOON SWINGS');
console.log(swings.getRapName());
// 생성자 함수 Rapper 프로토타입에 rapName 프로퍼티 추가
Rapper.prototype.rapName = 'P-TYPE';
console.log(Rapper.prototype.getRapName());
// 출력
// MOOD SWINGS
// P-TYPE
위 예제 중, 아래에 추가된 두 개의 라인을 보겠습니다. Rapper의 프로토타입 객체에 동적으로 임의의 rapName이라는 프로퍼티를 선언하고, 'P-TYPE'이라는 값을 할당했습니다. 프로토타입 객체에 메서드를 생성하는 것과 마찬가지의 원리입니다. 그리고, Rapper.prototype.getRapName( ) 형태로 프로토타입 메서드를 실행했습니다.
그럼 this는 어디에 바인딩 될까요? 복잡하게 생각할 것 없이, [자신을 호출한 객체]를 바인딩한다는 원칙을 그대로 적용합니다. 이 경우, getRapName( )이라는 메서드를 호출한 객체는 Rapper.prototype이라는 객체가 됩니다. 즉, this는 Rapper.prototype과 바인딩됩니다. 그럼 여기서 리턴하는 객체는 Rapper.prototype.rapName이 되는 것이죠.
여기서 한 가지 기억해 두어야 할 원칙은, [프로토타입 객체도 객체의 한 종류이다] 입니다. 프로토타입 객체가 프로토타입 체이닝의 핵심 객체이기 때문에 특별한 대우(?)를 받기는 하지만, 이도 역시 Javascript의 객체 중 하나일 뿐이라는 사실에 기반해 위의 예제가 작동한 것입니다. 지금까지 배운 프로토타입 객체의 특성을 잘 기억하되, 객체로서의 일반적인 특성을 잊지 않는다면 this 바인딩 역시 쉽게 이해하실 수 있을 것입니다.
'Programming > Javascript' 카테고리의 다른 글
10. Javascript 프로토타입 체이닝 (7) - 쓰기를 할 때의 프로토타입 체이닝 (0) | 2022.10.31 |
---|---|
10. Javascript 프로토타입 체이닝 (6) - 디폴트 프로토타입 객체의 변경 (0) | 2022.10.28 |
10. Javascript 프로토타입 체이닝 (4) - 데이터 타입 확장 (0) | 2022.10.23 |
10. Javascript 프로토타입 체이닝 (3) - 생성자 함수로 생성한 객체의 프로토타입 체이닝 (0) | 2022.10.23 |
10. Javascript 프로토타입 체이닝 (2) - 리터럴 객체의 프로토타입 체이닝 (0) | 2022.10.20 |