자바스크립트 프로토타입의 적당한 의미?
자바스크립트는 Java와 C++ 같은 클래스기반의 언어가 아닙니다.(ECMA6에서는 Class 문법이 추가되긴 했지만 이는 단순히 문법개념이고 자바스크립트 자체가 Class기반의 언어로 바뀌었다는 뜻은 아닙니다.) 클래스기반의 언어가 아니다보니 클래스 기반의 상속 모델을 그대로 구현하기가 불가능했고 이의 대안으로 활용되어 지는 것이 프로토타입 기반의 상속 모델입니다. 자바스크립트는 상속을 받는 대상이 가지는 Prototype(원형) 속성이 존재하고 Prototype 으로부터 부여된 메소드와 속성을 사용함으로써 부모 객체의 기능을 수행할 수 있습니다. 지금부터 상속의 관점에서 자바스크립트 프로토타입을 파헤쳐 보도록 하겠습니다.
예제코드부터 보도록 하지요 ^^
let f = function () {
this.a = 1;
this.b = 2;
}
let o = new f(); // {a: 1, b: 2}
f.prototype.b = 3;
f.prototype.c = 4;
console.log(o.a); // 1
console.log(o.b); // 2
console.log(o.c); // 4
console.log(o.d); // undefined
먼저 f라는 함수는 a와 b를 선언합니다. f 함수를 통해 o 객체를 생성했구요. f의 prototype 객체에 b와 c값을 추가하였습니다. 이제 새로 생성한 o객체의 a,b,c,d값을 출력해보면 어떤 결과를 볼수 있을까요?
- o.a의 값은 f를 선언했을 당시 할당했던 1값이 출력이 되어집니다.
- o.b의 값은 f를 선언했을 당시 할당했던 2값이 아니라 f의 prototype 객체에 할당했던 3값이 출력되어 집니다.
- o.c의 값은 2번과 동일하게 f의 prototype 객체에 할당하였던 4값이 출력됩니다.
- o.d의 값은 undefined가 출력됩니다. o객체, f객체 어디서도 d의 값을 할당한 적이 없기 때문입니다.
이 예제에서는 f를 생성자로 사용하여 객체를 생성하고 그 생성한 객체를 o에 할당합니다. o에 생성된 객체는 prototype 변수로 f 객체를 참조합니다. 이렇게 생성된 o 객체는 값을 출력할 때 o객체 내부의 값을 검색하게 됩니다. o 객체 내부에 a,b,c,d(상기 예제에서는 o객체 내부에 어떤값도 할당하지 않았습니다.)값을 출력한다면 자바스크립트 엔진은 o객체에서 아무 a,b,c,d중 아무 값도 검색되지 않을 것입니다. 그렇게 되면 자바스크립트 엔진은 o객체 내부에 아무 값도 없다는 것을 알게된 후 o 객체의 prototype 객체를 참조합니다. 정확히 말하자면 o 객체에 저장되어있는 o 객체의 프로토타입에 대한 링크를 읽고 o객체의 프로토타입을 찾아 a,b,c,d값을 검색하게 됩니다.(이 경우 f 객체를 찾아가게 됩니다.) 그리하여 o.a, o.b.. 등의 값은 o의 내부에 존재하지 않는 f의 값들을 출력하게 되는 것입니다.
다음은 메소드를 활용한 예제를 보겠습니다.
var o = {
a: 2,
m: function(b){
return this.a + 1;
}
};
console.log(o.m()); // 3
var p = Object.create(o); //p객체 생성
p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
console.log(p.m()); // 13
// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.
// 따라서 o의 함수 m을 상속 받으며,
// 'this.a'는 p.a를 나타내며 p의 개인 속성 'a'가 된다.
상기예제에서
- o.a의 값은 2이며 o.m은 o.a+1 의 결과값을 출력하는 함수(메소드)입니다.
- o를 프로토타입으로 p객체를 생성하였습니다.
- p.a의 값을 12로 할당하였습니다.
- p.m 메소드를 실행하면 메소드 내의 this.a 값은 o객체의 2 값이 아니라 p객체에 할당한 12값이 되어 13이 출력됩니다.
앞서 설명드린 바와 같이 o를 프로토타입(원형)으로 생성한 p 객체의 경우 p 객체 내에 값이 존재하지 않다면 o객체를 찾습니다. 그렇다면 p객체 내에 값이 존재한다면 당연히 o객체 내에서 값을 찾을 이유가 없어집니다. 이것이 p.m 메소드가 13을 리턴하는 이유입니다. p.m 메소드는 실행 당시 o.m 메소드를 찾아 실행하게 되고 o.m 메소드는 this.a 값을 p에서 먼저 찾기 때문에 p.a에 할당한 12값을 획득하여 작업을 수행합니다.
마무리
자바스크립트 내에서의 프로토타입은 앞서 설명드린 것보다는 더 복잡한 체계를 가집니다. 해당 글은 프로토타입에 대한 이해를 목적으로 추상적인 개념을 단순화 시키도록 시도한 글입니다. 조금 더 깊은 이해를 가지길 원하는 분들은 다음글을 참조하셔도 되고 , 구글에서 검색하면 엄청나게 많은 정보를 확인하실수 있을 것입니다.
항상 느끼지만 추상적인 개념에 대해서는 최대한 많은 글을 읽어보고 본질을 벗어나지 않는 선에서 자신만의 개념을 확립시키는 것이 좋을것 같다고 생각합니다. : )
감사합니다.