자바스크립트 프로토타입(prototype) 이해하기
prototype이란?
prototype(프로토타입)은 한국어로 원형이라는 뜻인데 자바스크립트에서는 프로토타입으로 상속 개념을 제공하고 있습니다. (자바스크립트에서는 객체간의 관계가 복사가 아니라 연결이 맺어진 것이기 때문에 상속보다는 위임이 좀 더 적절한 표현)
자바스크립트는 모든 객체들이 부모객체가 가진 메소드와 속성을 상속받는 것이 가능한데 사실 자바스크립트는 Java나 Python 등과 달리 클래스 개념이 없기 때문에 상속 기능이 없지만 프로토 타입이라는 것을 통해 상속을 흉내내도록 구현하고 있습니다. 그래서 자바스크립트는 프로토타입 기반 언어(prototype-based language)라고 불립니다. ES6 이후에 클래스가 생겨나긴 했지만 그것이 위와 같은 프로토타입 객체지향 모델을 폐지하고 나온 새로운 모델은 아니고 Java와 같은 객체 지향 프로그래밍 언어에서 사용하는 것과 유사하게 사용할 수 있도록 문법을 제공하는 것으로, ES6 이후 나온 클래스 또한 어디까지나 자바스크립트의 함수이며 내부적으로는 프로토타입 모델을 따르고 있습니다.
자바스크립트에서 함수란?
1
function Person() {}
자바스크립트에서 함수는 곧 객체입니다. 객체는 속성(property)을 가지고 함수 또한 property를 갖습니다. 기본적으로 위와 같이 함수를 정의한다면 Person 객체
와 함께 Person의 prototype 객체
가 함께 생깁니다. 이 때 생성된 객체의 부모 역할을 하는 것은 생성자 Person 자신이 아니라 prototype 객체입니다.
Constructor, prototype, instance
어떤 생성자 함수(Constructor)를 new
연산자와 함께 호출한다면 Constructor에서 정의된 내용을 바탕으로 새로운 instance가 생성됩니다. 이 때 instance에는 __proto__
라는 property가 자동으로 부여되고 이 property는 Constructor의 prototype property를 참조하게 됩니다.
__proto__
1
2
아기사자.__proto__; // 엄마사자
아기사자.__proto__ === 엄마사자.prototype; // true;
모든 객체는 __proto__
를 통해 자신이 물려받은 [[Prototype]] 값에 접근할 수 있습니다. 즉 참조하는 용도로 쓰이며 상위 객체가 무엇인지 알 수 있는 것입니다. 그런데 [[Prototype]] 내부 슬롯에는 직접 접근이 불가합니다. 이는 프로토타입 체인의 단방향을 지키기 위해서입니다.
1
2
3
4
5
6
const parent = {};
const child = {};
//child의 프로토타입을 parent로
child.__proto__ = parent;
//parent의 프로토타입을 child로
parent.__proto__ = child; // TypeError:Cyclic__proto__ value
프로토타입 체인이 단방향성을 지켜야 하는 이유는 위와 같이 코드를 짜면 서로가 자신의 프로토타입이 되는 비정상적인 경우가 만들어지기 때문입니다.
프로토타입 체인 (prototype chain)
자식은 부모로부터 자신이 물려받은 유전자를 활용할 수 있고, 부모 뿐만 아니라 더 상위 부모의 유전자 까지도 활용할 수 있습니다.
모든 프로토타입 체이닝의 종점은 Object.prototype
입니다.
1
2
3
function Person(name) {
this.name = name;
}
1
2
3
4
5
6
7
8
9
Person.prototype.sayMyName = function () {
console.log(`My name is ${this.name}`);
};
const me = new Person("LDK");
//hasOwnProperty는 Object.prototype의 메소드로
//객체가 특정 property를 가지고 있는지 나타내는 Boolean 값을 리턴한다.
console.log(me.hasOwnProperty("name")); //true
위 예제를 보면 Person 생성자 함수에 의해서 생성된 me라는 객체는 Object.prototype 메소드인 hasOwnProperty를 호출할 수 있다는 것을 알 수 있습니다. 객체는 chain rule(연쇄법칙) 구조로 property나 method를 활용하기 때문에 찾고자 하는게 me에서 없는 경우에는 상위 prototype에서 찾고 거기서 없다면 또 상위 prototype에서 찾고 최종적으로는 Object.prototype에서 찾게 되는 것입니다.
Today I Learned
오늘 이렇게 자바스크립트의 중요한 기본 개념인 프로토타입을 이해하였고 constructor
, __proto__
, prototype
이 어떤 관계를 갖고 있는지 알게되었습니다.
본 포스팅은 아래 사이트를 참고하여 작성하였습니다.
🔔포스팅 공지
개인 공부 기록용 블로그 입니다.
잘못된 부분이 있을 시 메일이나 댓글로 지적해주시면 감사드리겠습니다 :)
댓글남기기