자바스크립트는 프로토타입 기반 객체 지향 언어라고 표현한다. 그렇다면 대체 프로토타입은 무엇을 의미하는걸까? 먼저 자바스크립트에서 객체를 만드는 두 가지 방법을 보자.

var objectLiteral = {}; // 1
var objectConstructor = new Object(); // 2

첫 번째 Literal 방법은 객체를 만들어내는 단축어? 숏컷이고, 두 번째 생성자를 이용한 방법이다. 기본적으로 두 방법 모두 Object 생성자의 프로토타입을 상속 받아 생성되었다.

Prototype


자바스크립트는 클래스라는 개념이 없다. 그래서 기존의 객체를 복사해서 새로운 객체를 생성하는 프로토타입 기반의 언어이다. 이는 객체 원형인 프로토타입을 이용하여 새로운 객체를 만들어낸다. 이렇게 생성된 객체는 다른 객체의 원형이 될 수 있다. 그렇다면 프로토타입은 언제 사용하게 되는걸까? 다음의 예제를 보자.

function Person(){
    this.hand = 2;
    this.body = 1;
    this.nose = 1;
}

var kim = new Person();
var lee = new Person();
console.log(kim.hand); // 2
console.log(lee.hand); // 2

보통 객체는 이런 방식으로 사용하게 될 것이다. 이 코드에서는 Person이라는 함수를 통해서 kim과 lee 객체를 생성했다. 이들은 각자 3개의 속성을 가지고 있고 데이터 또한 동일하다. 메모리의 관점에서 보면 kim과 lee 객체가 생성되면서 총 6개의 변수가 메모리에 저장 되었을 것이다. 심지어 중복된 값이다... 개발자는 중복과 반복을 극혐하게 되는 것 같다.(저만 그럴수도...) 다음으로 Prototype을 사용하여 객체를 생성하는 코드를 살펴보자.

function Person(){}

Person.prototype.hand = 2;
Person.prototype.body = 1;
Person.prototype.nose = 1;

let kim = new Person();
let lee = new Person();

console.log(kim.hand) // 2
console.log(lee.hand) // 2

얼핏보면 위의 코드와 그렇게 차이가 없어 보인다. 어떻게 되었든 출력되는 값은 같으니 말이다. 다시 한번 메모리 관점에서 살펴보자. kim과 lee는 자신이 변수를 가지고 있는게 아니라, Person.prototype이라는 어떤 Object의 hand라는 속성을 공유하고 있다. 그렇다는 말은 위의 코드 처럼 생성된 객체의 수 만큼 변수가 저장되는 것이 아니라, 같은 생성자를 통해서 만들어진 객체들은 하나의 prototype 이라는 Object를 공유하고 있다는 뜻이다.

Prototype Object


Javascript에서 함수가 정의 될 때, 함수는 기본적으로 Constructor(생성자)가 부여된다. 생성자가 부여된 함수는 new를 통해서 객체를 생성할 수 있게된다. 또한 Prototype Object가 생성되고 이 Object와 함수가 가지고 있는 prototype 속성과 연결이 된다. 따라서, Person.prototype은 어떠한 Prototype Object와 연결이 되어있다. 위의 코드를 살펴봤을때, Person.prototype.hand가 정의 된다면, 이는 어떠한 Prototype Object의 하나의 속성으로 추가가 된다는 뜻이다.


그런데 신기한건 kim이라는 객체는 hand라는 속성을 가지고 있지 않음에도 불구하고 어디선가 값을 가져와서 '2'를 찍어내고있다. 이건 어디서 나타난걸까?

바로 이때 나타나는 개념이 Prototype Link 이다. kim을 까보면 __proto__ 라는 것을 가지고 있다. 이는 자신을 생성 했던 함수가 가지고 있는 속성들을 가르킨다. 자신의 부모의 속성들을 물려받은 것이다. 마치 DNA처럼 말이다. 때문에 kim.hand 라는 의미는 부모인 Person.prototype이 가르키고 있는 Prototype Object의 속성 중 hand라는 속성을 가르킨다.

이렇게 데이터들은 연결에 연결을 하고 있다. 이는 JavaScript의 핵심 개념이며, 괜히 "프로토타입 기반의 언어" 라는 말이 있는 것이 아니다.

이 글을 작성하면서 거의 100% 참고 했던 블로그를 소개해본다. 이 글보다 더욱 자세하며 쉽게 설명 되어있다. 절대 이 포스트 만으로 Prototype에 대해 완벽하게 이해했다고 생각하면 안된다. Prototype의 영역은 훨씬 더 깊고 넓다. 필자도 이제 겨우 한 걸음 나아간 것이고, 더욱 찾아보고 이 포스트를 업데이트 할 예정이다.

[참고] https://medium.com/@bluesh55/javascript-prototype-이해하기-f8e67c286b67