자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 그리고 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 property 또는 method를 상속받아 사용할 수 있게 한다. 이러한 부모 객체를 Prototype(프로토타입) 객체
또는 줄여서 Prototype(프로토타입)
이라 한다.
Prototype 객체
는 생성자 함수에 의해 생성된 각각의 객체에 공유 property를 제공하기 위해 사용한다.
결론적으로 쉽게 설명하면, 모델의 청사진을 만들 때 쓰는 원형 객체(Original form)이다.
Prototype
객체는 constructor property
를 갖는다. 이 constructor property
는 객체의 입장에서 자신을 생성한 객체를 가리킨다.
예를 들어 Person()
생성자 함수에 의해 생성된 객체를 foo
이라고 하자. 이 foo
객체를 생성한 객체는 Person()
생성자 함수이다. 이때 foo
객체 입장에서 자신을 생성한 객체는 Person()
생성자 함수이며, foo
객체의 Prototype
객체는 Person.prototype
이다. 따라서 Prototype
객체 Person.prototype
의 constructor property
는 Person()
생성자 함수를 가리킨다.
function Person(name) { this.name = name; } var foo = new Person('Lee'); // Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다. console.log(Person.prototype.constructor === Person); 👉 true // foo 객체를 생성한 객체는 Person() 생성자 함수이다. console.log(foo.constructor === Person); 👉 true // Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다. console.log(Person.constructor === Function); 👉 true
자바스크립트는 특정 객체의 property나 method에 접근시 객체 자신의 것뿐 아니라 __proto__
가 가리키는 링크를 따라서 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 접근할 수 있다.
즉, 특정 객체의 프로퍼티나 메소드 접근시 만약 현재 객체의 해당 프로퍼티가 존재하지 않는다면 __proto__
가 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례로 검색하는 것이 바로 프로토타입 체인이다.
Example
💻 Code
const car = { wheels: 4, drive(){ console.log("drive..."); }, }; const bmw = { color: "red", navigation: 1, }; bmw.__proto__=car; const x5 = { color: "white", name: "x5", }; x5.__proto__=bmw;
✔ Result
x5.name 👉 "x5" x5.color 👉 "white" x5.navigation 👉 1 x5.drive(); 👉 drive...
주의해야할 점
x5 👉 {color: "white", name: "x5"} for(let p in x5){ console.log(p); } 👉 color 👉 name 👉 navigation 👉 wheels 👉 drive // color와 name을 제외한 나머지들은 Prototpye에서 정의한 property이다. for(p in x5){ if(x5.hasOwnProperty(p)){ console.log('o', p); } else{ console.log('x', p); } } 👉 o color 👉 o name 👉 x navigation 👉 x wheels 👉 x drive Object.keys(x5); (2) ["color", "name"] Object.values(x5); (2) ["white", "x5"]
💻 constructor를 이용해보자
const Bmw = function (color){ this.color = color; }; Bmw.prototype = { constructor: Bmw, // 명시하지 않을 경우 z4.constructor === Bmw; 는 false값이 나온다 // 이런 현상을 방지하기 위해 Prototype으로 덮어씌우지 않고 하나씩 property를 추가하는 것이 좋다 wheels: 4, drive() { console.log("drive..."); }, navigation: 1, stop() { console.log("STOP!"); }, }; const z4 = new Bmw("blue"); z4.stop(); 👉 STOP! z4 instanceof Bmw 👉 true z4.constructor === Bmw; 👉 true