WEB/Java Script

Javascript- 프로토타입체이닝

비주얼라이즈 2016. 7. 3. 04:51



자바스크립트 - 프로토타입이란?


(나를 포함하는) 초급 개발자의 경우, 알아야할 것들이 한 두개가 아니다보니, 개발에 바로 쓰여야할 중요한 개념이아니고서야(사실 모르면서 개발에 써본적이 매우 있다.) 그냥  못본척 지나쳐버리는 개념들이 굉장히 많다. 나에게 이 Prototype 개념역시 그 중에 하나이다. 이전까지 대-충 알아왔지만, 한번도 깊게 기술적인 내용을 들여다 본적은 없었기에, 이번 기회를 통해 제대로 정리해보고자 이렇게 글로 정리하고있다.

* 그래서, 이 글에서 살펴볼 내용 : 자바스크립트의 '프로토타입' 개념



왜 프로토타입을 알아야 할까?


프로토타입 관련 개념이 자바스크립트에서 OOP 구현하는데 있어 기본 바탕이 되기때문이다.


*OOP란, object-oriented programming의 약자로, 모든 데이터를 오브젝트(객체)로 취급하여 프로그래밍하는 방법을 말한다. 이는 처리 요구를 받은 객체가 자기 자신의 안의 내용을 가지고 처리하는 방식을 의미한다.[각주:1]








프로토타입 개념을 살펴보기 전에 알고갈 것


바로 프로토타입 개념을 볼 수 도 있겠지만, 개인적인 경험으로 다시 기초적인 기술 내용을 살펴보게 되는 것 같다. 이 글에서는, 왠만하면 관련 개념에 대해서 알아야할 최소한의 정도까지만 다루고, 그 이상에 대해서는 글의 중심주제에서 벗어나지 않기위해 생략하려고한다.



즉, 이 '프로토타입 개념을 살펴보기 전에 알고갈 것' 의 내용을 알고있다면 skip하고모른다면 한번쯤 살펴보면 된다.



_____

자바스크립트는 '클래스' 개념이 없다.


객체지향 프로그래밍을 이야기할 때 쉽게 떠올리는 것이 자바(자바스크립트와는 다르다.)의 '클래스'개념이다. 그러나, 자바스크립트에는 '클래스'라는 개념이 없다. 


대신, 자바스크립트에서는 '객체 리터널'이나 '생성자 함수'로 '객체'를 생성한다. 

사실, 자바스크립트에서는 모든 것이 객체이다.


이와 관련해서 기술서의 내용을 살펴보면 다음과 같다.


자바스크립트에는 이러한 클래스 개념이 없다. 대신에 객체 리터럴이나 앞서 셜명했던 생성자 함수로 객체를 생성한다. 이렇게 생성된 객체의 부모 객체가 바로 '프로토타입'객체다. 즉, 상속 개념과 마찬가지로 자식 개체는 부모 객체가 가진 프로퍼티 접근이나 메서드를 상속받아 호출하는 것이 가능하다.[각주:2]

이와함께 조금 만 더 살펴보면, '암묵적 프로토타입 링크'라 불리는 개념이 있다.







_____

개념이해 - 암묵적 프로토타입 링크


자바스크립트의모든 객체는 자신의 부모인 프로토타입 객체를 가리키는 참조 링크 형태의 숨겨진 프로퍼티가 있다. ECMAScript에서는 이러한 링크를 암묵적 프로토타입 링크(implict prototype link)라고 부르며 이러한 링크는 모든 객체의 [[prototype]] 프로퍼티에 저장된다. 그리고 이 책에서는 이러한 링크를 [[prototype]]링크라고 명명한다.[각주:3]



자바스크립트에서 모든 객체는 자신을 생성한 생성자 함수의 prototype 프로퍼티가 가리키는 프로토타입 객체를 자신의 부모 객체로 설정하는 [[prototype]] 링크로 연결한다.







_____

prototype 프로퍼티와 [[Prototype]]링크 구분 예제[각주:4]


//Person 생성자 함수
function Person(name){
    this.name = name;
}

//foo 객체 생성
var foo  = new Person('foo');

console.dir(Person);
console.dir(foo);

Person() 생성자 함수는 prototype 프로퍼티로 자신과 링크된 프로토타입 객체(Person.prototype)를 가리킨다. 그리고 앞서 설명한 자바스크립트 생성 규칙에 의하면 Person() 생성자로 생성된 foo 객체는 Person()함수의 프로토타입 객체를 [[Prototype]]링크로 연결한다. 

* 결국 이 코드의 결과로, prototype 프로퍼티나 [[Prototype]]링크는 같은 프로토타입 객체를 가리키고 있다.




결국, 자바스크립트에서 객체를 생성하는 건 생성자 함수의 역할이지만, 생성된 객체의 실제 부모 역할을 하는 건 생성자 자신이 아닌 생성자의 prototype 프로퍼티가 가리키는 프로토타입 객체다.[각주:5]





글쓴이 :  "하 - 어렵다. "



조금만 더 참고 살펴보자. (나만 어려운 게 아닐 것이라는 자기 최면 중)


이번에는 마냥 코드를 바라보거나, 어려운 용어만 보기보다는 '크롬 개발자도구> 콘솔'에서 이와 관련한 짧은예제 코드를 입력하고 그 결과 형태를 살펴볼 것이다. 실제 우리가 마주할 화면이기도하고, 꽤 익숙할(?) 화면 이기때문에 그냥 개념만 줄줄 외우는 것보다는 도움이된다.





_____

크롬 콘솔창에서 실행하는 예제 : Prototype 프로퍼티와 [[Prototype]]링크 구분


다음 사진은 자바스크립트 프로토타입 개념을 이해하기위해 크롬 개발자도구의 콘솔창에서 직접 타이핑 하여 적은 뒤, 캡쳐한 사진이다. 자세히 한번 들여다 보자.


글쓴이 : 개인적으로 많이 봐왔던 영역이나, 그렇게 깊게 기술적으로 탐구해본 적이 없었다. 그래서 반성하면서 보고있다.








화면을 살펴보면,  위의 Person() 생성자 함수의 prototype 프로퍼티foo 객체의 __proto__ 프로퍼티(이것은 [[prototype]] 프로퍼티를 의미한다.) 같은 프로토타입 객체를 가리키고 있다는 것을 알 수 있다. 해당 프로토타입 객체constructor 프로퍼티Person() 생성자 함수를 가리키고 있다.[각주:6]


__proto__ 프로퍼티는 모든 객체에 존재하는 숨겨진 프로퍼티로, 객체 자신의 프로토타입 객체를 가리키는 참조 링크 정보다.


헷갈릴 수록 용어정리가 굉장히 중요하다. 더욱이 우리나라와 같이 비 영여권 국가의 경우 기술서 번역과정에서 동일한 개념에 대해 다른 용어로 사용하고있는 경우가 많기때문에 찝찝한 느낌이 조금이라도 든다면, 해당 개념에 대해 별도로 메모 해두는 것이 학습하는데 많은 도움이 된다. 



ECMAScript에서는 이것을 [[Prototype]] 프로퍼티로 정하고, 내부적으로만 사용된다고 명시하고있지만, 크롬파이나 파이어폭스 같은 브라우저에서는 __proto__ 프로퍼티로 명시적으로 제공하고 있다. 따라서 __proto__ 프로퍼티나 [[Prototype]] 프로퍼티는 같다고 간주하면 된다.[각주:7]




여기까지 자바스크립트에서의 '프로토타입' 개념과,  쉽게 착각할 수 있는 두 가지 프로토타입 용어의 개념에 대해서 살펴보았다. 한번에 너무 많은 기술내용을 우겨넣기보다는 여기까지의 내용을 먼저 곱씹어가며 직접 살펴보자.


글쓴이 : 이 글의 기술 내용과 관련하여, 선배 개발자분들의 조언 또는 오류내용 지적(?) 등 다양한 의견 감사히 받고 있습니다.











  1. [네이버 지식백과] 객체지향프로그래밍 [object-oriented programming] (두산백과) [본문으로]
  2. 송형주, 고현준 지음, "인사이드 자바스크립트", 한빛미디어, 2014, p.121 [본문으로]
  3. 위의책, p.121 [본문으로]
  4. 위의 책, p.122 [본문으로]
  5. 위의 책, p.122 [본문으로]
  6. 위의 책, p.123 [본문으로]
  7. 위의 책, p.124 [본문으로]