JS의 프로토타입

자바스크립트는 프로토타입 기반 언어라고 불린다. 프로토타입이라는게 뭘까?

간단한 예시

function Person() {
	this.eyes = 2
  this.nose = 1
}

const a = new Person()
const b = new Person()

a 와 b 인스턴스는 eyesnose공통으로 가지고 있는데 메모리에는 eyes와 nose가 각각 2개씩 총 4개가 할당된다. 만약 100개의 인스턴스를 만들면 200개의 변수가 메모리에 할당된다. 이런 문제를 Prototype 으로 해결할 수 있다!

function Person() {}
Person.prototype.eyes = 2
Person.porotoype.nose = 1
const a = new Person()
const b = new Person()
console.log(a.eyes) // 2

이게 가능한 이유는 Person.prototype이라는 빈 객체가 존재하고 Person함수를 통해 생성된 객체를 이 객체를 참조할 수 있기 때문이다.

JS에는 Prototype Link와 Prototype Object가 존재하고 이 둘을 통틀어 Prototype이라고 부른다.

Prototype Object

우선 JS에서 객체는 언제나 함수로 생성된다.

function Person() {}
const pObj = new Person() // 함수로 객체를 생성

객체 리터럴 방식도 마찬가지다.

const a = {}

위 코드는 const a = new Object() 와 같다. Object라는 함수를 통해서 객체가 생성되는 것이다. ( 기본적으로 내장된 함수 )

Object와 마찬가지로 Array, Function 모두 함수로 정의되어 있다. 이것이 Prototype Object와 무슨 관계일까?

함수가 정의될 때는 2가지 일이 동시에 이루어진다.

  1. 해당 함수에 constructor 자격 부여 ( 객체를 만들 수 있는 자격 부여 )

이것이 함수가 new 키워드를 사용할 수 있는 이유이다.

  1. 해당 함수의 Prototype Object 생성 및 연결

image

생성된 함수는 prototype 프로퍼티를 통해 Prototype Object에 접근할 수 있다. Prototype Object는 일반적인 객체와 같고 기본적으로 constructor, __proto__ 프로퍼티를 갖고있다.

constructor는 Prototype Object와 같이 생성되었던 함수를 가리키고 있다.

__proto__Prototype Link 이다.

function Person() {}
Person.prototype.eyes = 2
Person.prototype.nose = 2
const a = new Person()
console.log(a.eyes) // 2

다시 위에서 했던 예시를 보면 a 에는 eyes 라는 프로퍼티가 없는데 어떻게 Prototype Object에 있는 속성을 참조할 수 있을까?

그 이유는 a 가 갖고있는 __proto__ 속성 때문이다.

prototype 속성은 함수만 갖고있지만 __proto__ 속성은 모든 객체가 빠짐없이 갖고 있다.

이 속성은 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다. ( 여기서 a 인스턴스는 Person 함수로부터 생성되었으니 Person.Prototype을 가리킨다. )

image

kim 객체는 eyes를 직접 가지고 있지 않기 때문에 eyes 속성을 찾을 때 까지 상위 프로토타입을 탐색한다.

최상위인 Obejct의 Prototype Object까지 도달했는데도 못찾았을 경우 undefined를 리턴한다.

이렇게 __proto__ 속성을 통해 상위 프로토타입과 연결되어있는 형태를 프로토타입 체인이라고 한다.

이런 프로토타입 체인 구조 때문에 모든 객체는 Object의 자식이라고 불리고, Object.Prototyp에 있는 모든 속성을 사용할 수 있다.

Reference

https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67


Written by@[HongDongUk]
공부한 것을 소소하게 적는 블로그.

GitHubFacebook