들어가기 전에
생성자를 통해 상속하고 부모와 연결하는 방법에 대해서 알아보고 prototype과 __proto__의 차이에 대해서 다시 한번 살펴봅니다.
학습 목표
생성자를 통해 상속하고 부모와 연결해 메소드를 상속해 사용할 수 있습니다.
핵심 단어
- 생성자
- 상속
- 부모
- 메소드
들어가기 전에
생성자를 통해 상속하고 부모와 연결하는 방법에 대해서 알아보고 prototype과 __proto__의 차이에 대해서 다시 한번 살펴봅니다.
학습 목표
생성자를 통해 상속하고 부모와 연결해 메소드를 상속해 사용할 수 있습니다.
핵심 단어
아직 Person과 PersonPlus가 아무런 연관이 없기 때문에
PersonPlus에서 Person에 소속되어 있는 sum 메소드를 호출하면 오류가 나게 됩니다.
현재 상태를 그림으로 살펴보겠습니다.
Person과 Person의 prototype 그리고 PersonPlus와 PersonPlus의 프로토타입 객체는 서로를 참조하고 있습니다.
그리고 PersonPlus를 통해 생성된 kim이라는 객체의 __proto__는
자신을 생성한 생성자의 prototype 객체인 PersonPlus 객체의 prototype 객체를 가리키고 있습니다.
이때 만약 kim에서 avg라는 함수를 호출하면 kim이라는 객체에 avg라는 프로퍼티가 없기 때문에
kim 객체의 __proto__가 가리키는 PersonPlus에서 avg라는 프로퍼티를 찾아서 실행하게 됩니다.
이번에는 kim이라는 객체에서 sum이라는 함수를 호출해보겠습니다.
kim 객체 안에 sum이라는 프로퍼티가 없기 때문에 __proto__를 따라서
PersonPlus의 prototype 객체를 확인해보지만 역시나 sum이라는 프로퍼티가 존재 하지 않기 때문에
에러가 발생하게 됩니다.
따라서 우리는 PersonPlus의 porotype에 찾는 프로퍼티가 없을때는 Person의 prototype 객체를 확인하도록
연결해줘야합니다.
따라서 PersonPlus의 porotype의 __prototype__이 Person의 prototype 객체를 가리키도록 하면 됩니다.
이제 위와 같이 동작하도록 코드를 수정해보겠습니다.
function Person(name,first,second){
this.name = name;
this.first = first;
this.second = second;
}
Person.prototype.sum = function(){
return this.first + this.second;
}
function PersonPlus(name, first, second, third){
Person.call(this,name,first,second);
this.third = third;
}
PersonPlus.prototype.__proto__ = Person.prototype;
PersonPlus.prototype.avg = function(){
return (this.first+this.second+this.third)/3;
}
var kim = new PersonPlus('kim', 10, 20, 30);
console.log("kim.sum()", kim.sum());
console.log("kim.avg()", kim.avg());
하지만 __proto__는 표준이 아니기 때문에 많은 예제에서는 Object.create()를 사용합니다.
Object.create를 이용해 Person.prototype을 __proto__로 하는 새로운 객체를 생성한 후
PersonPlus의 prototype으로 지정합니다.
function Person(name,first,second){
this.name = name;
this.first = first;
this.second = second;
}
Person.prototype.sum = function(){
return this.first + this.second;
}
function PersonPlus(name, first, second, third){
Person.call(this,name,first,second);
this.third = third;
}
//PersonPlus.prototype.__proto__ = Person.prototype;
PersonPlus.prototype = Object.create(Person.prototype);
PersonPlus.prototype.avg = function(){
return (this.first+this.second+this.third)/3;
}
var kim = new PersonPlus('kim', 10, 20, 30);
console.log("kim.sum()", kim.sum());
console.log("kim.avg()", kim.avg());
console.log("kim.constructor",kim.constructor);
이때 constructor를 출력해보면 personPlus가 아닌 Person으로 나오는 것을 확인할 수 있습니다.
이 문제는 다음 시간에 살펴보겠습니다.
생각해보기
위의 실습에서 constructor를 출력해보면 personPlus가 아닌 Person으로 나오는 이유는 무엇일까요?
comment
Object.create는 지정한 프로토타입 객체 및 속성을 새 객체로 만들어버리기 때문
그래서 person을 가리킴
머리가 아파지고 있음...ㅜㅜ
PersonPlus.prototype.__proto__ = Person.prototype 은 PersonPlus의 Prototype객체의 __proto__가 가리키는걸 변경해준것이고
PersonPlus.prototype = Object.create(Person.prototype); 은 PersonPlus의 Prototype객체 자체가 Person의
prototype 객체로 변경된것인것 같습니다. 그러면 Person.prototype 의 constructor 프로퍼티가 가르키던 Person을
가리키게 되는것 같습니다.
PersonPlus.prototype = Object.create(Person.prototype);
이 코드 떄문에 kim의 consturctor가 Person으로 나옵니다.
Object.create로 __proto__가 Person을 가르키는 객체를 대입해주었기 때문