상속을 할 때 Object.create()과 new 연산자의 차이는?

Park, Jinyong·2020년 6월 20일
0

Question & Answer

목록 보기
3/3

자바스크립트에서 pseudoclassical한 방법으로 상속을 할 때 아래와 같은 방법으로 한다.

function Human(name, age) {
  this.name = name;
  this.age = age;
}

Human.prototype.sleep = function() {
  console.log(`${this.name} is sleeping...`);
}

function Programmer(name, age, lang) {
  Human.apply(this, arguments);
  this.lang = lang;
}

Programmer.prototype = Object.create(Human.prototype);
Programmer.prototype.constructor = Programmer;

Programmer.prototype.writeCode = function() {
  console.log(`${this.name} is coding a ${this.lang} program!`); 
}

const park = new Programmer('Park', 25, 'JavaScript');

park.sleep(); // Park is sleeping...
park.writeCode(); // Park is coding a JavaScript program!

인스턴스를 만들어서 해당 인스턴스의 __proto__로 프로토타입 객체를 확인해보면 그 내부에도 똑같이 __proto__ 프로퍼티가 존재한다.

park.__proto__;
// Human
//  - constructor: ƒ Programmer(name, age, lang)
//  - writeCode: ƒ ()
//  - __proto__: Object

"그럼 프로토타입 객체도 일종의 인스턴스로 볼 수 있지 않을까?" 라는 생각에new 연산자로 인스턴스를 생성한 뒤, 이를 프로토타입 객체로 설정해도 제대로 동작하리라 생각했다.

// Programmer.prototype = Object.create(Human.prototype);
Programmer.prototype = new Human();

기대한 바와 같이 정상적으로 동작하고 있음을 확인할 수 있다.

const park = new Programmer('Park', 25, 'JavaScript');

park.sleep(); // Park is sleeping...
park.writeCode(); // Park is coding a JavaScript program!

하지만, 좋은 방법이라고 할 수 있을까? Programmer의 프로토타입 객체를 확인해보면 Object.create()를 이용했을 때와 차이가 보인다.

Programmer.prototype = Object.create(Human.prototype);
Programmer.prototype.constructor = Programmer;

console.log(Programmer.prototype);
// Human
//  - constructor: ƒ Programmer(name, age, lang)
//  - writeCode: ƒ ()
//  - __proto__: Object
Programmer.prototype = new Human();
Programmer.prototype.constructor = Programmer;

console.log(Programmer.prototype);
// Human {name: undefined, age: undefined, constructor: ƒ, writeCode: ƒ}
//  - age: undefined
//  - constructor: ƒ Programmer(name, age, lang)
//  - name: undefined
//  - writeCode: ƒ ()
//  - __proto__: Object

new 연산자를 이용한 방법에서만 추가로 name, age 프로퍼티를 확인할 수 있는데, 이는 불필요한 프로퍼티이다. 따라서, new 연산자를 이용한 방법은 우리가 원하는 바로 동작하기는 하지만, 불필요한 프로퍼티를 생성하므로 비효율적인 상속 방법이라고 할 수 있겠다.

1개의 댓글

comment-user-thumbnail
2021년 8월 16일

new는 생성자의 프로퍼티까지 가져오고 Object.create는 생성자의 prototype만 가져오네요. 각 상황의 맞게 사용하는게 정답이겠네요.

답글 달기