Frontend/JavaScript
[JavaScript] 코어 자바스크립트 6장 - 프로토타입
zeo.y
2023. 6. 7. 14:46
반응형
아래 책을 읽고 정리한 내용입니다.
http://www.yes24.com/Product/Goods/78586788
💡 프로토타입 기반 언어인 자바스크립트에서는 객체를 원형으로 삼고 이를 참조함으로써 상속과 비슷한 효과를 얻는다.
프로토타입 개념 이해하기
new
연산자로Constructor
를 호출하면 인스턴스가 만들어지는데, 이 인스턴스의 프로퍼티인__proto__
는Constructor
의prototype
을 참조한다.- 생성자 함수의
prototype
에 어떤 메서드가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티를 사용할 수 있다. prototype
은 객체이며, 이를 참조하는__proto__
역시 객체이다.
코드를 통해 자세히 알아보자.
- Person이라는 생성자 함수의
prototype
에 getName이라는 메서드를 지정했다. - Person의 인스턴스인 suzi는
__proto__
를 통해 getName을 호출할 수 있다. - 그런데 왜
undefined
출력될까?this
바인딩이 대상이 잘못되었기 때문이다.- getName은 메서드로서 호출되어 바인딩 대상은 suzi가 아니라
suzi.__proto__
이고,suzi.__proto__
에는_name
이 없기 때문에undefined
가 출력되는 것이다.
__proto__
는 생략 가능한 프로퍼티이므로,suzi.getName()
처럼 바로 호출할 수 있고 이때 Suzi가 정상적으로 출력된다.
var Person = function(name) {
this._name = name;
};
Person.prototype.getName = function() {
return this._name;
};
var suzi = new Person('Suzi');
console.log(suzi.__proto__.getName()); //undefined
console.log(suzi.getName()); //Suzi
내장 생성자 함수 Array를 통해 확인해 보자.
- Array의
prototype
에 있는 메서드가 arrInstance의__proto__
에 들어 있는 것을 볼 수 있다.
const arrInstance = new Array();
console.dir(Array);
console.dir(arrInstance);
cf) ES5.1 명세에는 __proto__
가 아니라 [[prototype]]
이라는 명칭으로 정의되어 있다.
정리하자면, 프로토타입 개념은 다음과 같다.
- 자바스크립트는 함수에 자동으로 객체
prototype
프로퍼티를 생성해 놓는데, 해당 함수를 생성자 함수로서 사용할 경우, 그로부터 만들어진 인스턴스에는 숨겨진 프로퍼티__proto__
가 자동으로 생성되며, 이 프로퍼티는 생성자 함수의prototype
을 참조한다. __proto__
는 생략이 가능하기 때문에 인스턴스는 생성자 함수의prototype
에 있는 메서드를 마치 자신의 것처럼 접근할 수 있다.
책의 그림 6.3과 6.6의 도식을 보면 이해하기 쉽다!
Constructor 프로퍼티
- 생성자 함수의 프로퍼티인
prototype
객체 내부에는constructor
라는 프로퍼티가 있다. (인스턴스의__proto__
도 마찬가지) - 이 프로퍼티는 원래의 생성자 함수(자기 자신)를 참조한다.
- 인스턴스로부터 그 원형이 무엇인지 알 수 있는 수단이다. (상속 흉내가 가능해진 측면)
다음 각 줄은 모두 동일한 대상(생성자)을 가리키다.
[Constructor]
[Constructor].prototype.constructor
[instance].constructor
[instance].__proto__.constructor
Object.getPrototypeOf([instance]).constructor
const instance = new Array();
//모두 [Function: Array]를 출력
console.log(Array);
console.log(Array.prototype.constructor);
console.log(instance.constructor);
console.log(instance.__proto__.constructor);
console.log(Object.getPrototypeOf(instance).constructor);
프로토타입 체인
- 어떤 데이터의
__proto__
프로퍼티 내부에 다시__proto__
프로퍼티가 연쇄적으로 이어진 것을 프로토타입 체인이라 하고, 이 체인을 따라가며 검색하는 것을 프로토타입 체이닝이라고 한다. - 어떤 메서드를 호출하면 자바스크립트 엔진은 데이터 자신의 프로퍼티를 검색해서 원하는 메서드가 있으면 그 메서드를 실행하고, 없으면
__proto__
를 검색한다. 메서드가 있을 경우 그 메서드를 실행하고, 또 없으면 다시__proto__
를 검색한다. - 자바스크립트의 모든 데이터의 프로토타입 체인 끝에는
Object.prototype
가 있다.prototype
이 객체이기 때문이다. - 프로토타입 체인은 무한대의 단계(다중 프로토타입 체인)로 확장이 가능하다.
cf) 메서드가 오버라이딩될 때(인스턴스에서 동일한 메서드를 가지고 있는 경우), 원본은 그대로 둔다. 따라서 프로토타입 체인을 통해 원본에도 접근이 가능하다.
반응형