Table of Contents
- 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍 언어다
-
객체지향 프로그래밍의 핵심은 상속인데, 자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거한다
- 아래 그림과 같이 getArea 라는 메서드를 프로토타입 객체로 보내면 중복을 제거할 수 있다
- 생성자 함수가 생성한 모든 인스턴스는 생성자 함수와 쌍을 이루는 프로토타입 객체의 모든 프로퍼티와 메서드를 상속받는다
- 프로토타입은 어떤 객체의 상위 객체 역할을 하는 객체로서 다른 객체에 공유 프로퍼티를 제공한다
- 모든 객체는
[[Prototype]]
이라는 내부 슬롯을 가지며, 이 내부 슬롯의 값은 프로토타입의 참조다.[[Prototype]]
에 저장되는 프로토타입은 객체 생성 방식에 의해 결정된다. 즉 객체가 생성될 때 객체 생성 방식에 따라 프로토타입이 결정되고[[Prototype]]
에 저장된다
[[Prototype]]
내부 슬롯에는 직접 접근할 수 없지만, 위 그림처럼__proto__
접근자 프로퍼티를 통해 자신의 프로토타입, 즉 자신의[[Prototype]]
내부 슬롯이 가리키는 프로토타입에 간접적으로 접근할 수 있다- 생성자 함수는
prototype
프로퍼티로 프로토타입 객체에 접근 가능하고, 객체는__proto__
프로퍼티로 객체에 접근 가능하고, 프로토타입은constructor
프로퍼티로 생성자 함수에 접근 가능하다 - 모든 객체는
__proto__
프로퍼티를 통해 자신의 프로토타입, 즉[[Prototype]]
내부 슬롯에 간접적으로 접근할 수 있다 __proto__
은 객체가 소유하고 있는 프로퍼티가 아니고,Object.prototype
의 프로퍼티를 상속받은 것이다- 모든 객체는 프로토타입의 계층 구조인 프로토타입 체인에 묶여있다. 자바스크립트 엔진은 객체의 프로퍼티 또는 메서드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면
__proto__
프로퍼티가 가리키는 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 프로토타입 체인의 종점, 즉 프로토타입 체인의 최상위 객체는 Object.prototype이며, 이 객체의 프로퍼티와 메서드는 모든 객체에 상속된다 - 코드 내에서
__proto__
프로퍼티를 직접 사용하는 것보다는 프로토타입을 참조하고 싶은 경우에는 Object.getPrototypeOf 메서드를 사용하고, 프로토타입을 교체하고 싶은 경우에는 Object.setPrototypeOf 메서드를 사용할 것을 권장한다
객체 instanceof 생성자 함수
instanceof
연산자는 우변의 생성자 함수의prototype
프로퍼티에 바인딩된 프로토타입 체인안에 좌변의 객체의 프로토타입이 속하는지를 확인한다
프로퍼티 in 객체
in
연산자는 객체 내에 특정 프로퍼티가 존재하는지 여부를 확인한다in
연산자는 객체의 프로퍼티뿐 아니라, 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인하기 때문에, ES6에서 도입된Reflect.has
메서드가 더 정확하다고 할 수 있다
for (변수 선언문 in 객체) {}
- 객체의 모든 프로퍼티를 순회하며 열거하려면
for...in
문을 사용한다 for...in
문은 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티중에서 프로퍼티 어트리뷰트[[Enumerable]]
의 값이 true인 프로퍼티를 순회하며 열거한다for...in
문은 자신의 고유 프로퍼티뿐 아니라 상속받은 프로퍼티도 열거한다. 그래서 자신의 프로퍼티만 열거하기 위해서는Object.keys/values/entries
메서드를 사용하는 것이 낫다