오승환, https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
PoiemaWeb, https://poiemaweb.com/js-prototype
참고 사이트에 내용을 개인적으로 복습하기 편하도록 재구성한 글입니다.
자세한 설명은 참고 사이트를 살펴보시기 바랍니다.
자바스크립트는 Java, C++과 같은 class
기반 객체 지향 프로그래밍 언어와 다르게 prototype
기반 객체 지향 프로그래밍 언어입니다. class
기반의 언어는 객체 생성 이전의 class
를 정의하고 이를 통해 인스턴스를 생성하고 상속 개념을 구현합니다. 자바스크립트는 class
없이 객체를 생성할 수 있고, prototype
객체를 통해 상속 개념을 구현합니다.
ES6에서 class
문법을 추가했지만, 이 또한 프로토타입 기반으로 구현된 것이며 자바스크립트가 클래스 기반으로 바뀌었다는 것을 의미하지는 않습니다.
자바스크립트는 new
연산자와 생성자 함수의 조합을 통해 여러 개의 객체를 쉽게 만들 수 있습니다. 여기서 생성자 함수는 일반 함수와 같지만 객체 생성의 목적으로 만들어진 대문자로 시작하는 함수를 의미합니다.
function Person() {
this.eyes = 2;
this.nose = 1;
};
const Tomas = new Person();
const James = new Person();
console.log(Tomas.eyes); // 2
console.log(Tomas.nose); // 1
console.log(James.eyes); // 2
console.log(James.nose); // 1
여기서 문제점이 생깁니다. Tomas
와 James
는 eyes
와 nose
프로퍼티를 공통적으로 가지고 있는데, 메모리에는 eyes
와 noes
가 두 개씩 총 4개 할당됩니다. 객체를 100개 만들면 200개의 변수가 할당되는 셈입니다. 이를 해결하기 위해 프로토타입이 사용됩니다.
function Person() {};
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
const Tomas = new Person();
const James = new Person();
console.log(Tomas.eyes); // 2
console.log(Tomas.nose); // 1
console.log(James.eyes); // 2
console.log(James.nose); // 1
간략하게 설명하자면 Person.prototype
이라는 빈 객체를 메모리에 할당하고, 이 객체 안에 공통으로 사용할 데이터를 집어넣습니다. 그리고 Person()
생성자 함수로부터 생성된 객체들은 메모리에 존재하는 Person.prototype
객체를 참조하여 그 안에 데이터들을 사용합니다.
자바스크립트는 함수를 생성하면 함수뿐 아니라 Prototype Object도 생성합니다.
Prototype Object
여러 객체가 공유할 데이터를 담는 객체
위 그림에서 눈 여겨봐야할 것은 생성된 함수 안에 존재하는 prototype
과 Prototype Object 안에 존재하는 constructor
, __proto__
입니다.
prototype
함수 객체만 가지고 있는 프로퍼티로 자신이 생성될 때 같이 생성되는 Prototype Object를 참조합니다.
constructor
Prototype Object만 가지고 있는 프로퍼티로 자신과 같이 생성된 함수 객체를 참조합니다.
__proto__
함수를 포함한 모든 객체가 가지고 있는 프로퍼티로 자신을 생성한 생성자 함수의 Prototype Object를 참조합니다. 함수 객체는 Function.prototype
을 가리킵니다.
위 그림에서 함수 객체는 __proto__
를 실제로 포함하지만 설명 과정에서 불필요하므로 생략됐습니다.
함수와 Prototype Object는 prototype
과 constructor
를 통해 서로를 참조합니다.
new
연산자와 생성자 함수의 조합으로 객체를 생성합니다. 생성된 객체는 __proto__
속성으로 자신을 생성한 함수의 Prototype Object를 참조하게 되고, Prototype Object 내의 데이터를 사용할 수 있게 됩니다.
new
연산자와 생성자 함수의 조합으로 또 다른 객체를 생성하더라도 위와 같은 원리로 자신을 생성한 함수의 Prototype Object를 참조하게 되고, 데이터를 공유합니다.
Person()
생성자 함수와 같이 생성된 Person Prototype Object 역시 자신을 생성한 부모 생성자 함수가 존재합니다. 이는 네이티브 객체의 Object()
생성자 함수이며, Person Prototype Object의 __proto__
속성은 Object()
생성자 함수의 Object Prototype Object를 참조합니다. Object Prototype Object는 최상위에 위치하기 때문에 __proto__
속성은 null
을 가리킵니다. 이렇게 __proto__
속성을 통해 상위 Prototype Object와 연결되어 있는 형태를 프로토타입 체인이라 합니다.