MuhammadJ MuhammadJ - 1 month ago 4
Javascript Question

How to - correctly - delegate the Class prototype

If you jump to first Answer in this question you'll see that he used

Employee.prototype = new Person();
to inherit the
Person.prototype
to
Employee.prototype
, But When I learned about JavaScript OOP Course from Udacity they used
Employee.prototype = Object.create(Person.prototype);

instead.
What's the correct one :

Employee.prototype = new Person();


or

Employee.prototype = Object.create(Person.prototype);


or

Employee.prototype = Person.prototype;


If this question is duplicated please refer me some good answers.

Answer

Employee.prototype = Object.create(Person.prototype); is the cleanest.

With Employee.prototype = new Person(); you'll find that assignments to this in Person affect all of your Employee instances. Perhaps you don't want that. There could be other side effects, too.

For example (using some ES2015 syntax):

function Person(name = "fred") {
  this.name = name;
}

function Employee(...args) {
  Person.call(this, ...args);
}

Employee.prototype = new Person();


var e1 = new Employee();
console.log(e1.name); // fred

You need to read the Person code to understand why all of your employees are called fred by default. That's trivial in this case, but in the real world a lot of functions are long and stateful and easy to mis-read.

Imagine if Person depended on some outside state. The value of Employee.prototype could change based on whether or not some other code has already executed. You don't want that kind of uncertainty in your prototype chain.

For example:

let personCount = 0;
function Person() {
  this.id = personCount ++;
}

// ...

Employee.prototype = new Person();
// what `id` do Employees inherit? we don't know!
// it depend on how many times `Person` has been called,
//  and by creating `Employee.prototype` we changed the state even further. Uhoh.

Object.create(Person.prototype) is easier to reason about because there are no user function calls; there is no logic. You only need to check the static Person.prototype to see what you're inheriting.

It is still possible for prototypes to have mutable values, and therefore some uncertainty, but the act of creating an object itself doesn't have side effects so this kind of bug is less likely.

With Employee.prototype = Person.prototype;, changes to Employee.prototype will affect all Person instances. You probably don't want that.

Comments