Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
관리 메뉴

0strich

[JavaScript] Prototype & Prototype Chain 본문

Front End/JavaScript

[JavaScript] Prototype & Prototype Chain

0strich 2020. 1. 7. 21:11

Prototype

new 키워드의 기능에 대해 숙지하고 prototype에 대해 알아보자

prototype은 javascript 에서에서는 존재하지 않는 클래스 개념을 비슷하게 구현할 수 있고, 상속을 할 수 있게 해주는 것 같다.

또한 익숙해지면 다른 언어보다 자유도가 높은 코딩을 할 수 있다고 한다.

(하지만 아직 실력이 안되니 좀 더 공부할 필요가 있다... ㅠㅠ)

 

Javscript의 Prototype 에는 Prototype Object와 Prototype Link가 존재한다.

 

javscript에서 함수를 만들면 prototype object 가 같이 생성이 되고 prototype 프로퍼티로 접근이 가능하다.

다음과 같이 func() 함수를 만들고 prototype 프로퍼티로 접근해 보자

 

 

Prototype Object를 펼쳐보니 constructor와 __proto__ 가 있다.

constructor Prototype Object와 같이 생성되었던 함수를 가리킨다.

__proto__  Prototype Link이다. 

 

__proto__ 는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다.

이 부분을 이해하기 위해서는 Prototype Chain이라는 개념이 필요해 보인다.


Prototype Chain

__proto__ 가 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다면, 만약에 여러 번 조상을 거쳤다면 어떻게 될까?

function GrandFather() {}
GrandFather.prototype.hair = '대머리'

function Father() {}
Father.prototype = Object.create(GrandFather.prototype)
Father.prototype.face = '잘생김'

function Son() {}
Son.prototype = Object.create(Father.prototype)
Son.prototype.name = '사이타마'

var hero = new Son()

hero.face	// 잘생김
hero.hair	// 대머리
hero.name	// 사이타마

예시는 내가 좋아하는 만화 원펀맨의 주인공인 사이타마의 출생이다 (예시 참 잘 만듦)

설명하자면 우선 생성자로 사용할 의도로 만든 함수가 GrandFather(), Father(), Son()이다.

Object.create()를 사용하여 Father()과 Son()의 prototype 객체에 순서대로 상위 객체를 상속받았다.

GrandFather()의 Prototype Object에 hair 프로퍼티 추가

Father()의 Prototype Object에 face 프로퍼티 추가

Son()의 Prototype Object에 name 프로퍼티 추가

 

hero라는 객체에 new operator를 사용하고 생성자로는 Son()을 사용했더니 잘생긴 대머리 사이타마가 출력이 된다.

원하는 내용은 출력이 되는 것 같다.

prototype.constructor 누락

상속이 올바르게 되었는지 확인하기 위해 hero 객체를 열어보았다.

상속이 올바르게 되었다면 __proto__에 연결된 constructor 프로퍼티가 상속해준 생성한 함수를 가리켜야 한다.

하지만 hero 객체의 __proto__ 에는 최상위 생성자인 GrandFather()을 제외하고는 constructor 가 존재하지 않는다.

Prototype 객체를 상속하는 과정에서 constructor 가 누락된 것이다.

Object.create()를 사용하게 될 경우, 새로운 객체를 생성해서 파라미터로 받은 값을 저장하고 넘겨준다.

때문에 상속받는 함수의 prototype객체에는 새로운 객체가 저장이 되는 것이다.

prototype.constructor 누락 해결

function GrandFather() {}
GrandFather.prototype.hair = '대머리'

function Father() {}
Father.prototype = Object.create(GrandFather.prototype)
Father.prototype.constructor = Father
Father.prototype.face = '잘생김'

function Son() {}
Son.prototype = Object.create(Father.prototype)
Son.prototype.constructor = Son
Son.prototype.name = '사이타마'

var hero = new Son()

hero.face	// 잘생김
hero.hair	// 대머리
hero.name	// 사이타마

constructor가 누락되었다면 prototype 객체를 상속받은 다음에 constructor를 다시 설정해주면 된다.

다시 hero 객체의 내부를 열어보면 조금 변한 것을 확인할 수 있다.

객체의 __proto__ 가 바로 상위 객체를 가리키는 것을 확인할 수 있다.

또한 상위 객체의 constructor 가 자신의 생성자 함수를 가리키는 것을 확인할 수 있다.

 

이러한 방법을 사용하는 이유는 javascript 언어는 OOP 구현을 염두에 두고 만든 언어가 아니기 때문이다.

그렇기 때문에 OOP 구현을 하기 위한 여러 가지 연구가 이루어져 왔다. ES6에서 class 가 등장하기 전까지는 prototype과 Object.create()를 이용한 상속을 하고, constructor를 재설정해주는 번거로운 방법으로 OOP를 구현해 왔다.

this 또한 염두에 두고 사용해야 하기 때문에 새로 등장한 class 문법을 사용하는 것이 더 깔끔한 코드가 될 것 같다.

상속 중에 고려해야 할 this의 사용법은 다른 글에서 리뷰해야겠다.

 

 

 

※ 잘못된 부분이나 수정해야 할 부분이 있다면 댓글에 남겨주세요~ 바로 반영하도록 하겠습니다!

'Front End > JavaScript' 카테고리의 다른 글

[JavaScript] Promise(비동기 처리)  (0) 2020.01.18
[JavaScript] Class & Super  (0) 2020.01.04
[JavaScript] Instantiation Patterns  (0) 2019.12.29
[JavaScript] 객체 간의 상속 (Object.create())  (0) 2019.12.29
[JavaScript] New  (0) 2019.12.28
Comments