본문 바로가기

자바스크립트

[javascript] 프로토타입과 상속, 그리고 프로토타입 체인, 최상위 프로토타입

반응형
공부한거 정리용

작성순서

1. 프로토타입이란?

 

2. 프로토타입의 상속

 

3. 프로토타입 체인(및 프로토타입 체이닝)

 

4. 최상위 프로토타입(모든 프로토타입의 뿌리)


1. 프로토타입(Prototype) 이란?

프로토타입은 한글로는 '원형' 을 의미한다. 원형은 어느 대상의 근본이 되는 형태라고 이해할 수 있다. 이 원형을 우리 신체적 특성으로 가져온다면, '유전자' 라고 이해할 수 있다. 이러한 유전자에는 우리 신체를 이루는 모든 정보들이 저장되어 있다.

 

이를 기반으로 자바스크립트가 프로토타입을 기반으로 하는 객체 지향 언어라고 했을 때, 우리가 사용하고 있는 array, function 등의 객체의 모든 관련 정보들이 프로토타입 이라는 유전자에 저장되어 있다는 말로 이해할 수 있다.

 

즉, 프로토타입은 우리가 사용하는 객체와 관련된 모든 정보를 가지고 있는 원형 또는 유전자라고 간략하게 정의내릴 수 있을 듯 하다.


2. 프로토타입의 상속

객체의 프로토타입은 참조 링크 형태(객체가 언제든 참조하여 사용할 수 있도록 연결된 상태)로  [[Prototype]] 내부의 프로퍼티(속성) 에 저장된다. 참조 링크 형태로 저장됨으로써 동일한 부모의 프로토타입을 상속 받는 객체는 모두 동일한 프로퍼티와 메서드를 공유한다. 또한 만약에 부모 프로토타입의 정보가 변경(수정)된다면, 그의 상속을 받는 객체들의 프로토타입도 동일하게 변경된다.

 

아래 예시는 배열 arr에서  Array.Prototype (부모 프로토타입) 으로 부터 상속받은,

arr의 프로토타입에 저장된  프로퍼티와 메서드의 일부이다. 

-----

[이러한 정보를 토대로 우리는 알 수 있다 배열과 관련한 모든 매서드들이 보이지도 않는데 어디서 온 것인지

왜 사용할 수 있는 것인지 말이다.]

------

let arr = [1,2,3,4];

arrary의 프로토타입 참조 링크


3. 프로토타입 체인

아래 예시처럼 객체 내에서 존재하지 않은 메서드를 호출하면 [object Object] 가 뜨는 것을 확인할 수 있는데, 왜 그런걸까?

const object = {
    이름:"프로토타입"
}

console.log(object.toLocaleString())

// 출력 ) [object Object]

이는  프로토타입 체인이라는 특성에 의해서 가능하다. 프로토타입 체인은 상위 프로토타입과 연쇄적으로 연결된 구조를 의미하는데,

 

어떤 객체에 접근해서 특정 메서드를 호출하면,   객체 내에 주어진 객체의 프로퍼티나 메서드에 접근 후  원하는 것을 찾지 못하면, 프로토타입 체인을 따라 숨겨져 있는 프로토타입에 접근함으로써 해당하는 메서드를 호출하는 것을 프로토타입 체이닝이라 한다.


너무 지저분 해서 알아보기 힘들었기에 

이를 단계별로 정리해보면 다음과 같다.

1. ojbect 객체의 toLocaleString() 메서드를 호출하기 위해 ojbect 객체 내부를 탐색한다.

2. 찾지 못했다면, 프로토타입 체인을 통해 숨겨져 있는 상위 프로토타입에 진입하여 탐색한다.

3. 상위 프로토타입에서 toLocaleString() 메서드를 발견했으므로 이를 호출한 결과로 [object Object] 를 반환한다.

ㄴ 이러한 검색 과정을 '프로토타입 체이닝' 이라 한다.

예시의 객체를 콘솔에 출력하면, name 프로퍼티 이외에 [[Prototype]] 이 프로퍼티로 들어 있는 것을 확인할 수 있다.

즉, 기존에 존재하는(눈에 보이는) 프로퍼티와 매서드에서 찾고자 하는 프로퍼티와 매서드를 대조해보고,

일치하지 않으면 숨겨져 있던  [[Prototype]] 프로퍼티에 접근해서 다시 대조를 실시하는 것이다. 

다시 말하지만,  '[[Prototype]]' 은 '참조링크 형태'로 부모 프로토타입(상위 프로토타입)과 연결되어 있다. 
따라서 '프로토타입 체이닝'은 자식이 가지고 있지 못한 물건이 있다면, 부모 프로토타입에 접근해서 필요한 
물건을 찾은 후 빌려가는 것으로 이해할 수 있다.

( [[Prototype]] 은 

object 객체의 내부에는  name 프로퍼티뿐 아니라, 보이지 않는 곳에[[prototype]]  프로퍼티가 숨겨져 있다.


4.  최상위 프로토타입(모든 프로토타입의 뿌리)

자바스크립트에서 윈시타입을 제외하면 모두 객체에 해당한다. 그리고 모든 객체는 각자의 부모 프로토타입을 가지며, 부모 프로토타입들 또한 자신의 부모 프로토타입을 가지게 되는데, 이를 최상위 프로토타입이라 한다.

 

또한  배열, 함수, 랩퍼 객체 등의 모든 자바스크립트 내장 객체는  공통적으로 Object.Prototype을 최상위 프로토타입으로 가진다. 

다시 말해, 배열, 함수, 래퍼 객체의  부모 프로토타입은 서로 달라도, 하나의 뿌리에서 시작된다는 의미이다.

단, 구분해야 할 점은 <객체 리터럴로 생성된 객체와 배열, 함수 등에 의해 생성된 객체의 프로토타입은 서로 다르다>는 것이다. 

즉 최상위 프로토타입은 'Object.Prototype' 으로 동일하지만,

'객체 리터럴'로 생성된 객체는 '부모 프로토타입'과 '최상위 프로토타입'이 'Object.Prototype' 으로 명칭이 동일하고,

'배열'의 '부모 프로토타입'은 'Array.Prototype' 이며, '최상위 프로토타입'은 'Object.Prototype'이다. 

이 외에도 '함수'나 '랩퍼 객체'도 '자신만의 부모 프로토타입'을 가지고, '최상위 프로토타입'은 'Object.Prototype' 인 것은 같다.

 

 

※ 프로토타입은 언제 설정될까?

더보기
프로토타입은 배열, 함수 등의 내장 객체가 생성되는 시점에 같이 설정된다.  또한 최상위 프로토타입으로 Object.Prototype 이 설정된다.

 

반응형