[JavaScript] 프로토타입(Prototype)

YJ·2023년 7월 10일
0

자바스크립트는 흔히 프로토타입 기반 언어라 불리는데, 그럼 자바스크립트에만 있는 요상한 문법인 프로토타입이 도대체 뭔지!

프로토타입(Prototype)

'코어 자바스크립트'에 있는 위 이미지를 풀어서 설명해보면 아래와 같다.

자바스크립트는 함수에 자동으로 객체prototype 프로퍼티를 생성해 놓는데, 해당 함수를 Constructor(생성자) 함수로서 사용할 경우, 즉 new 연산자와 함께 함수를 호출할 경우, 그로부터 생성된 instance에는 숨겨진 프로퍼티인 ⎽⎽proto⎽⎽가 자동으로 생성되며, 이 프로퍼티는 Constructor 함수의 prototype 프로퍼티를 참조한다.
⎽⎽proto⎽⎽ 프로퍼티는 생략 가능하기 때문에 Constructor 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 instance에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있다.

✏️ 정리하면,

new 연산자로 Constructor를 호출하면 instance가 만들어지는데, 이 instance의 생략 가능한 프로퍼티인 ⎽⎽proto⎽⎽는 Constructor의 prototype을 참조한다!!

더 간단하게 prototype을 유전자라고 이해하면 쉽다.

function 기계 () {
  this.q = 'strike';
  this.w = 'snowball';
}

기계.prototype.name = 'kim';

var nunu = new 기계();

console.log(nunu)          // 기계 {q: 'strike', w: 'snowball'}
console.log(nunu.name)     // 'kim'

위 코드에서 실제로 nunu를 출력해보면 name: 'kim'은 전혀 보이지 않는다. 그러나 부모의 유전자에 기록이 돼있으면 즉, 부모의 prototype에 있으면 그걸 가져다 쓸 수 있게 된다.

그렇다면 부모 유전자에 있는걸 자식이 어떻게 사용할 수 있는 것일까?

프로토타입 체인 (Prototype Chain) & 프로토타입 체이닝 (Prototype Chaining)

객체에서 데이터를 뽑아내고 싶을 때(nunu.name) 자바스크립트에서 일어나는 일련의 과정을 살펴보자.

  1. nunu가 name을 가지고 있으면 ➡️ 출력
  2. nunu가 name을 가지고 있지 않으면 ➡️ nunu 부모 유전자 탐색 ➡️ 거기에 name이 있으면 출력
  3. nunu 부모 유전자에도 없으면 ➡️ 부모의 부모 유전자 탐색
  4. 부모의 부모의 부모...

Prototype 객체가 상위 prototype 객체로부터 메소드와 속성을 상속 받을 수도 있고, 또 그 상위 prototype 객체도 마찬가지이다.

이처럼 프로토타입이 상속되는 가상의 연결 고리프로토타입 체인(prototype chain)이라고 한다.
(코어 자바스크립트에서는 '어떤 데이터의 ⎽⎽proto⎽⎽ 프로퍼티 내부에 다시 ⎽⎽proto⎽⎽ 프로퍼티가 연쇄적으로 이어진 것'이라 설명하고 있는데, 이해하기 편한 쪽으로 받아들이면 될 것 같다.)

객체는 prototype chain을 타고 올라가며 속성과 메서드를 검색한다. 접근 방식은 자신으로부터 가장 가까운 대상부터 점차 먼 대상으로 나아가며, 원하는 값을 찾으면 검색을 중단한다.
이 과정을 프로토타입 체이닝(prototype chaining)이라 한다.

Prototype에 대한 오해❗️

많은 글들이 prototype을 설명할 때 class의 '상속'이라는 단어를 섞어 사용하기 때문에 흔히 class의 '상속'을 떠올리기 쉽다.
MDN만 하더라도 '자바스크립트에서는 객체를 상속하기 위하여 prototype이라는 방식을 사용합니다.' 라고 설명하고 있다.

하지만 엄밀히 말해 prototype의 상속은 class의 상속과 다른 개념이다.

자바스크립트에서는 '복사'를 통한 상속이 없으므로, prototype은 내용 복사 없이도 상속을 구현할 수 있게 해주는 방법이다.
프로토타입 기반 상속은 객체가 프로토타입 체인을 따라 올라가며 속성과 메서드를 찾는 방식을 이용한다. 객체 자체의 내용이 복사되는 것이 아니라, 해당 객체가 어떤 프로토타입을 가리키고 있는지를 나타내는 연결 고리를 통해 상속 관계를 구성한다.

즉, prototype이 하는 일은 상속이 아니라 연결이라고 이해하는 편이 더 알맞다.


※ 참고 자료
MDN
코어 자바스크립트
[10분 테코톡] 💼 크리스의 Prototype
JavaScript - prototype (1/2) : prototype이란?
JavaScript - prototype (2/2) : prototype chain
이거보고 prototype 이해 못하면 강의접음

profile
Hello

0개의 댓글