Java, C++과 같은 클래스 기반 객체지향 프로그래밍 언어와 달리 자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어이다. 따라서 프로토타입에 대해서 잘 이해해야 js를 사용하는데 편리하다.
쉽지는 않지만 그렇다고 그렇게 어렵지않다고 생각되는 프로토타입에 대해서 알아보자
보통 프로토타입은
무언가 제품을 만드는 과정에서 시험용으로 미리 만들어보는 물건을 의미한다.
이 표현이 우리 일상속에 녹아있는 프로토타입의 의미이다.
하지만 프로그래밍에서 프로토타입, 특히 JS에서 프로토타입은 조금 다른 의미를 가진다.
자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 그리고 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다. 이러한 부모 객체를 Prototype(프로토타입) 객체 또는 줄여서 Prototype(프로토타입)이라 한다.
자바스크립트에는 원래 class 문법이 존재하지 않았다. ECMAScript6에서 새로 도입되었다.
그전까지는 프로토타입으로 부모객체의 프로퍼티와 메소드를 객체지향의 상속처럼 상속받아서 사용할 수 있었다.
이 문법은 현재도 통용되는데 사실 JS는 기존의 기능을 변경하지않고 기존의 기능 위에 새로운 기능을 추가하는 식으로 진행되기때문이다.
본론으로 돌아와서
혹 chorme 의 검사 창을 본적이 있는가 어떤 객체를 콘솔에 찍고 출력을 해보면 객체 안에 엄청 많은 내용이 들어있는 것을 볼 수 있다.
가령 예를들어 다음의 객체를 생성하고 콘솔을 찍어봤다고 하자.
let obj = {
name : 'mhKang',
age : 30,
sex : 'male'
}
console.log(obj.toString()); //[object Object]
console.dir(obj);
위 내용을 콘솔창에서 확인하면 다음과 같다.
여기 [[Prototype]]타고 들어간 내용을 보면 실제로 내가 작성한 객체보다 많은 내용을 가지고 있는 모습을 볼 수 있다.
어째서 내가 만든 부분이 아닌 다른 내용이 포함되어 있을까?
ECMAScript의 글을 보면 다음과 같은 설명이 있다.
자바스크립트의 모든 객체는 [[Prototype]]이라는 인터널 슬롯(internal slot)를 가진다. [[Prototype]]의 값은 null 또는 객체이며 상속을 구현하는데 사용된다. [[Prototype]] 객체의 데이터 프로퍼티는 get 액세스를 위해 상속되어 자식 객체의 프로퍼티처럼 사용할 수 있다. 하지만 set 액세스는 허용되지 않는다.
즉 [[Prototype]]안의 값은 Prototype객체(부모 객체)이며 __proto__
로 접근할 수 있다는 것인데...
어렵네... 그렇게 어렵지 않다고 했던거 취소....
여튼 다시 설명하겠다.
만약 우리가 Person이라는 객체를 만든다고 하자
function Person(name, first, second){
this.name = name;
this.first = first;
this.second = second;
}
이런 함수형 객체를 만들면 Person은 Person.prototype을 가진다.
그리고 이 Person에 prototype에 sum이라는 함수를 생성하면
Person.prototype.sum = function(){}
Person은 sum 함수를 가지고 있지 않지만 Person의 prototype이 가지게 된다.
그리고 Person을 이용하여 다른 객체를 생성하면
let kim = new Person('kim',10,20)
let lee new Person('lee',10,10)
그 객체들의 __proto__
는 Person이 아니라 Person.prototype을 가르킨다.
즉 kim이나 lee에서 sum을 쓰고 싶으면 __proto__
타고 올라가 해당 기능을 불러올 수가 있는 것이다. ---> Prototype chain
__proto__
는 자식 Object에서 부모 Object의 prototype에 대한 주소를 가지는 요소라고 할 수 있다.
이를 보고 자식 Object에 없는 기능을 __proto__
를 타고 올라가 쓸 수가 있는 것이다.
어떤 value가 Object의 프로토타입인지 알려면
object.isPrototypeof(value)를 쓰면 된다.
Prototype은 이름이 너무 생소해서 문제지만 class의 상속기능과 비슷하다는 것은 알고가는 것이 좋을 듯하다.
참고
생활코딩 Javascript 객체지향프로그래밍 15.prototype vs proto https://youtu.be/wT1Bl5uV27Y
Poiemaweb 5.14 Prototype 프로토타입 https://poiemaweb.com/js-prototype