프로그램에 필요한 핵심 속성을 추상화한 뒤, 객체의 상태(프로퍼티)와 동작(메서드)을 하나의 논리적인 단위로 묶어 효율적이고 이해하기 쉬운 프로그램을 만들어 내는 방식.
자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 없앤다.
function Circle(radius){
this.radius = radius;
this.getArea = function(){
return Math.PI * this.radius ** 2;
}
}
const circle1 = new Circle(1);
위와 같이 생성자 함수를 통해 여러개의 인스턴스를 만들어내는 경우 매번 동일한 getArea 메서드를 생성한다. 이와 같은 중복을 제거하기 위해 프로토타입을 기반으로 상속을 구현한다. 즉, 시조에 정보를 새기고 자손들은 필요할 때마다 시조에게 물어봐서 정보를 가져온다.
function Circle(radius){
this.radius = radius;
}
Circle.prototype.getArea = function (){
return Math.PI * this.radius ** 2;
}
프로토타입 객체란 위에서 설명한 시조에 정보를 새긴 것을 모아둔 객체다. 모든 객체는 하나의 프로토타입을 갖고 생성자 함수와 연결되어 있다.
__proto__ 접근자 프로퍼티모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, [[prototype]] 내부 슬롯에 간접적으로 접근할 수 있다. __proto__ 프로퍼티는 객체가 직접 소유하는 프로퍼티가 아니라 Object.prototype의 프로퍼티다. 모든 객체는 상속을 통해 Object.prototype.__proto__ 프로퍼티를 사용할 수 있다.
__proto__접근자 프로퍼티를 통해 프로토타입에 접근하는 이유.순환 참조하는 프로토타입 체인이 만들어지면 프로토타입의 체인 종점이 존재하지 않기 때문에 프로퍼티를 검색할 때 무한루프에 빠진다. 때문에 프로토타입 체인은 단방향 링크드 리스트로 구현되어야 한다.
__proto__접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다.모든 객체가 proto 접근자 프로퍼티를 사용할 수 있는 것은 아니기 때문.
만약 프로토타입의 참조를 획득하고 싶다면 Object.getPrototypeOf 메서드를 사용하고, 프로토타입을 교체하고 싶다면 Object.setPrototypeOf 메서드를 사용하자.
prototype 프로퍼티는 함수 객체만 소유하며 이는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다. 일반 객체 또는 non-constructor(화살표 함수, 메서드)는 prototype 프로퍼티를 소유하지 않는다.
(function (){}).hasOwnProperty('prototype'); // true;
({}).hasOwnProperty('prototype'); // false;
모든 프로토타입은 constructor 프로퍼티를 갖는다. 이 constructor 프로퍼티는 prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킨다. 이 연결은 생성자 함수가 생성될 때, 즉 함수 객체가 생성될 때 이뤄진다.
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성된다.
객체가 생성되기 이전에 생성자 함수와 프로토타입은 이미 객체화되어 존재한다.
이후 생성자 함수 또는 리터럴 표기법으로 객체를 생성하면 프로토타입은 생성된 객체의 [[Prototype]] 내부 슬롯에 할당된다.
객체는 다양한 방식으로 생성되지만 추상 연산 OrdinaryObjectCreate에 의해 생성된다는 공통점이 있다. OrdinaryObjectCreate는 필수적으로 자신이 생성할 객체의 프로토타입을 인수로 전달 받는다. 즉, 프로토 타입은 추상 연산 OrdinaryObjectCreate에 전달되는 인수에 의해 결정된다.
객체 리터럴 방식은 프로퍼티를 추가할 때 객체 리터럴 내부에 프로퍼티를 추가해야 하지만 Object 생성자 함수는 일단 빈 객체를 생성한 이후 프로퍼티를 추가해야 한다.
자바스크립트는 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없으면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 이를 프로토타입 체인이라고 한다.
프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 프로토타입 체인을 따라 프로토타입 프로퍼티를 검색하여 떺어쓰는 것이 아니라 인스턴스 프로퍼티로 추가한다. 이와 같이 상위 객체, 클래스가 가지고 있는 메서드를 하위 객체, 클래스가 재정의 사용하는 방식을 오버라이딩이라고 한다. 또한 이처럼 상속 관계에 의해 프로퍼티가 가려지는 현상을 프로퍼티 섀도잉이라고 한다.
내용이 많이 어려워서 다시 한 번 읽어보고 추가 정리해볼 것!
📖 모던자바스크립트 딥다이브 19장 프로토타입(259p)