Computer Science/JavaScript

자바스크립트 Chapter 17 Prototype Inheritance and Prototype Chain

Write and Remember 2019. 5. 11. 02:19

 

모든 자바스크립트 개발자가 알아야 할 개념 33가지

 

Chapter 17. Prototype Inheritance and Prototype Chain

 

자바스크립트 프로토타입(prototype)에 대한 내용은 여러 번 다뤘는데

 

프로토타입 기반 언어이므로

 

계속해서 중요하다고 강조하는 것 같다.

 

실습은 크롬 개발자 도구(F12)를 사용해보자.

 

2019/05/06 - [Computer Science/JavaScript] - 자바스크립트 Chapter 14 Factories and Classes

 

자바스크립트 Chapter 14 Factories and Classes

자바스크립트 핵심 컨셉 33가지 Chapter 14 Factories and Classes 이번 장에서는 Factories와 Classes를 살펴보자. 자바스크립트에서 팩토리 함수란, 함수가 객체를 반환할 때를 의미한다. 간단한 팩토리 함수의..

jeongw00.tistory.com

 

2019/05/10 - [Computer Science/JavaScript] - 자바스크립트 Chapter 16 new, Constructor, instanceof and Instances

 

자바스크립트 Chapter 16 new, Constructor, instanceof and Instances

자바스크립트 핵심 컨셉 33가지 new 연산자(operator)와 Constructor부터 알아보자. new를 사용하면 새 빈 객체가 생성되고 this를 새롭게 생긴 객체에 바인딩한다. 새로 생성된 __proto__ 라는 객체에 생성자 함..

jeongw00.tistory.com

 

다시 한번 프로토타입을 살펴보자..

 

자바스크립트의 모든 객체에는 [[Prototype]]이라는 속성(property)이 있다.

 

이중 괄호는 코드에서 직접적으로 접근할 수 없다.

 

const a = {}

 

getPrototypeOf() 메서드를 사용해서 접근해보자.

 

Object.getPrototypeOf(a);
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

 

또 다른 방법은 __proto__ 속성(property)을 이용하는 것이다.

 

__proto__는 객체의 내부 [[Prototype]]을 노출하는 속성(property)이다.

 

a.__proto__
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

 

결과는 동일하다!

 

객체의 속성 또는 메서드에 접근하려고 하면 

 

JavaScript는 객체 자체를 먼저 검색하고 객체가 발견되지 않으면 

 

객체의 [[Prototype]]을 검색한다. 

 

객체와 해당 [[Prototype]]을 모두 참조한 후에도 일치하는 것이 발견되지 않으면 

 

JavaScript는 링크된 객체의 프로토 타입을 검사하고 

 

프로토 타입 체인의 끝에 도달할 때까지 계속 검색한다.

 

프로토타입 체인 끝에는 Object.prototype이 있다.

 

모든 객체는 Object의 속성과 메서드를 상속받는다.

 

a.toString()
// [object Object]

 

toString() 메서드는 위에서 정의한 적이 없지만

 

a는 Object에서 상속받은 빈 객체이므로 Object에 있는

 

모든 속성이나 메서드를 사용할 수 있다.

 

또 다른 예로 배열을 살펴보자.

 

const b = []

b.__proto__

// [constructor: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]

 

b는 Array.prototype에서 상속받았으므로

 

concat(), find(), map() 등 위에서 정의하지 않은 메서드를

 

사용할 수 있다.

 

아! 그래서 push(), filter()을 사용할 수 있었던 것이다.

 

그 역할을 하는 건 [[Prototype]]이다!

 

그러므로 자바스크립트는 프로토타입 기반 언어라고 할 수 있는 거다.

 

또한 Array()로 설정된 프로토타입의 생성자(Constructor) 속성(property)을 확인할 수 있다.

 

 

생성자 속성(Constructor property)은 함수의 객체를 만드는 데 사용되는

 

객체의 생성자 함수를 반환한다.

 

b.__proto__.__proto__

// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

 

b -> Array -> Object (프로토타입 체인)

 

동일한 것을 참조하고 있는지 확인해보자.

 

b.__proto__ === Array.prototype // true
b.__proto__.__proto__ === Object.prototype // true

 

isPrototypeOf() 메서드로도 확인이 가능하다.

 

Array.prototype.isPrototypeOf(b) // true
Object.prototype.isPrototypeOf(Array) // true

 

Chapter 16에서 다룬 instanceof로도 확인이 가능하다.

 

b instanceof Array // true

 

정리해보면,

 

모든 자바스크립트 객체 내부에는 [[Prototype]] 속성이 있고

 

__proto__을 통해 노출될 수 있으며 객체를 확장하고

 

생성자의 [[Prototype]]에 있는 속성(property)과 메서드(method)를

 

상속받는다. 

 

이러한 프로토타입은 체인으로 연결될 수 있으며

 

체인은 Object.prototype으로 끝이 난다.

 

그 이상은 null을 반환한다.