자바스크립트에서 프로토타입이란 객체의 원형을 가지고 새로운 객체를 만들어 내기 위한 것이다.
프로토타입을 이용하면 객체의 특성을 확장할 수 있다.
자바스크립트 객체는 자신을 생성하기 위해 사용된 객체원형을 가지고 있다.
이것이 프로토타입(Prototype)이다.
자바스크립트의 객체는 Object 객체의 기반으로 확장되었기에 Object객체의 Prototype이 객체의 끝점이라고 볼 수 있다.
function test(){};
var T = new test();
console.log(T);
//console.log(T) 결과값
test {}
__proto__:
constructor: ƒ test()
length: 0
name: "test"
arguments: null
caller: null
prototype:
constructor: ƒ test()
__proto__: Object
__proto__: ƒ ()
[[Scopes]]: Scopes[1]
__proto__: Object
콘솔의 결과값을 보면 __proto__
와 constructor
를 보면 T
라는 객체를 만들어 내기 위한 연결을 보여주고 있다.
prototype
을 보게되면 해당되어진 객체 T는 함수 객체이며 이 객체의 생성자는 test()이다.
console.log(T.__proto__ === test.prototype) // true
var T
는 new로 만들어진 function test()
라는 자신의 프로토타입으로 사용하여서 만들어졌다는 말이다.
갑자기 Prototype Object 와 Prototype Link 에 대해서 이야기하는 것 같지만 위에서 보듯이 __proto__
와 constructor
를 보면 각각이 무엇을 의미하는지 알아야 할 것이다.
그것을 정의하는 것이 Prototype Object 와 Prototype Link 이며 이것이 함수 객체를 이루는 구조를 이해하는데 도움을 줄 것이다.
constructor
에 생성되었던 함수를 가르킨다.constructor
와 연관이 있다.var A
라는 객체가 있다면 이것은 생성자(constructor)가 아니고 var 라는 변수임으로 console.log(A)
를 찍으면 __proto__
만 보이며 이것을 따라가면 constructor
안의 prototype
을 볼 수 있다.A.prototype.name = '내용'
이런 식으로 써도 에러만 뜰뿐이다.__proto__
을 말하는 것이다.constructor
과 prototype
을 볼 수 있다. 생성자(constructor) 일 때 함수객체(function func(){}).prototype을 쓸 수 있는 것이고, 변수에 담은 것은 A.prototype를 쓸 수 없다. __proto__
는 프로토타입을 공유되어 만들어지는 객체들의 연결고리임을 알아두자.
위의 내용을 보고도 이해가 그리 쉽게 되질 않는다면 Prototype Link를 연결해보면 조금 더 쉽게 이해 될 것이다.
var Avar = function(){};
var Bvar = new Avar();
Avar.prototype.say = function(){
console.log('Hi :D');
}
Avar.say(); // error
Bvar.say(); // Hi :D
Avar.prototype.say(); // Hi :D
Bvar.__proto__.say(); // Hi :D
이미지를 보고 아래 소스를 같이 본다면 조금더 이해되질 않을까 생각된다.
Prototype은 하나의 Prototype을 생성하여서 다른 객체들과 공유 하는 것이다.
Avar
의 prototype을 만들면 prototype의 객체가 따로 생기며
Bvar
와 공유하게 된다.
그런데 이상하게도 Avar.say()
는 에러이며, Bvar.say()
는 제대로 나온다.
이건 Prototype Link와 연관있다. 연결고리가 다른 것이다.
이것을 Prototype Chain 이라고 부른다.
스코프체인처럼 __proto__
를 기준으로 체인이 걸리게 된다.
그렇다면 위 그림을 보면 Bvar
의 __proto__
는 현재 Avar가 만든 prototype에 걸려있으며
Avar
의 __proto__
는 function prototype에 걸려있다.
그래서 Avar.say()
는 에러이고 Bvar.say()
는 스코프체인처럼 위의 부모를 찾아서 가져오는 것이다.
그러면 바로 가져올려고 한다면
위의 소스처럼 Bvar.__proto__.say()
를 해서 가져올 수 있다.
결국 Prototype Chain으로 이루어 져있고 prototype은 공유를 하는 것이다.
프로토타입에 대해서 너무 어렵게 처음에 접근한 것 같았다.
공부를 하다보니 기초적으로 스코프체인과 비슷한 모습을 보였고 일정한 규칙이 보이기 시작했다.
이 프로토타입을 공부하다보니 자바스크립트를 객체적으로 표현하면 어떻게 될 지 조금이나마 감은 잡힌 것같다.