프로토타입이란 객체 원형을 의미하고 모든 객체는 원형으로부터 체이닝을 통해서 상속받아서 프로퍼티나 메서드를 사용할 수 있다.
자바스크립트는 원시값을 제외한 모든 것들이 객체로 이루어져 있고, 프로토타입 기반의 객체지향 언어이다.
객체 지향이란 객체(다양한 타입의 값들을 key와 value로서 하나의 단위로 만든 자료구조)의 상태와 상태를 조작하는 메서드를 가지는 하나의 기능을 담당하는 부품들을 통해서 프로그램을 만들어 나가는 것을 말한다.
상속은 객체 지향 언어의 핵심으로 어떤 객체의 프로퍼티나 메서드를 상속받아 그대로 사용하는 것을 말한다. 만약 인스턴스를 생성할 때마다 같은 프로퍼티와 메서드를 만든다면 메모리 낭비이다. 자바스크립트는 프로토타입을 기반으로 상속을 구현해서 불필요한 중복을 제거한다.
모든 객체는 [[Prototype]]이라는 슬롯을 가지며 저장되는 값은 프로토타입의 참조다. 프로토타입은 객체의 생성 방식에 의해서 결정된다. 예를 들어서 객체 리터럴로 생성된 객체는 Object 객체의 프로토타입이고, 생성자 함수를 통해서 생성된 객체는 생성자 함수 prototype에 바인딩된다.
_ _ prototype _ _ vs .prototype
- [[prototype]] 슬롯에는 직접적으로 접근할 수 없다.
- _ _ prototype _ _를 통해서 프로토타입 객체에 간접적으로 접근할 수 있다.
- _ _ prototype _ _ 은 Object.prototype.prototyp으로 Object.protype의 프로퍼티이다.
- _ _ prototype _ _과 prototype은 사용하는 주체가 다르다.
- prototype은 함수 객체만이 소유한다.
빌트인 객체 Object, Number, String 모두 생성자 함수다.
객체 리터럴을 통해서 생성된 객체는 Object.prototype을 가르킨다. Object 생성자 함수에 null, undefined를 넣게 되면 추정연산을 통해서 Object.prototype을 가르키는 빈객체를 내보낸다.
장점
-
간단하다.
클래스 기반의 상속에서는 class등의 부가적인 문법이 필요하고, class를 선언하고 class로부터 인스턴스를 만드는 과정을 거쳐야한다. 하지만 프로토타입 상속은 간단하게 객체를 만들고 객체간의 상속관계를 규정할 수 있다.
-
불필요한 코드를 줄일 수 있다.
-
동적타이핑
객체와 객체까리 직접적으로 상속관계를 가지기 때문에 프로토 타입의 객체를 런타임시에 동적으로 수정하여 자식객체에서 사용이 가능하다. 런타임시에 유연한 프로그래밍이 가능하게 한다.
단점
- 런타임시에 객체를 수정할 수 있기 때문에 버그를 유발할 수 있다.
- 프로토타입 객체에대한 meta-data를 제공하지 않는다.
- 상위의 프로토타입을 변경했을 경우 생기는 side effect가 굉장히 커진다.
프로토타입과 클래스 기반의 상속의 차이점
클래스 기반 상속은 class라는 개념이 존재하고 이를 수반해서 interface, abstract class 등의 추가적인 개념 또한 존재하지만
프로토타입 기반 상속은 객체라는 개념만 존재하고 객체들간의 관계설정을 통해서 상속을 구현한다.