1

While reading through https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance I saw that we should replace the Teacher's prototype with a new one, which has its prototype set to Person:

Teacher.prototype = Object.create(Person.prototype);
Object.defineProperty(Teacher.prototype, 'constructor', { 
    value: Teacher, 
    enumerable: false, // so that it does not appear in 'for in' loop
    writable: true });

I'd rather do it this way, it seems more logical to me:

Teacher.prototype.__proto__ = Person.prototype

As far as I understand, it ends up with the same result and the constructor stays correct, I do not have to replace it.

Is there any difference between MDN's approach and mine?

//EDIT As @ Asutosh pointed out, MDN discourages from using __proto__ (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto). However, MDN also says to use Object.setPrototypeOf instead. So, can I do this:

Object.setPrototypeOf(Teacher, Person.prototype)

instead of original

Teacher.prototype = Object.create(Person.prototype);
Object.defineProperty(Teacher.prototype, 'constructor', { 
    value: Teacher, 
    enumerable: false, // so that it does not appear in 'for in' loop
    writable: true });
mnj
  • 2,539
  • 3
  • 29
  • 58
  • 2
    __proto__ usage is deprecated in some manner. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto – Asutosh Aug 16 '20 at 15:19
  • @Asutosh That's interesting, thanks. Then, what about this, instead: `Object.setPrototypeOf(Teacher, Person.prototype)` – mnj Aug 16 '20 at 15:22
  • 1
    This is also discouraged. – Asutosh Aug 16 '20 at 15:23
  • Ahh, again :) Ok, I get it. However, I'm still just curious, would my proposed way of setting prototype break something (let's completely forget about the MDN's discouragement of doing it this way). I'm trying to understand how JS works. – mnj Aug 16 '20 at 15:27
  • 1
    No it does not break anything. – Asutosh Aug 16 '20 at 15:32

2 Answers2

1

Remember that in JavaScript, a prototype isn't some concept of a future object (like a class) - - it's an actual instance that has state and behavior. Making a new instance isn't so much about inheritance as it is about the specific state of a particular instance.

If you don't create a new instance for the prototype, you can wind up with your new object sharing a specific prototype instance with other unintended object instances. Changes to that specific instance's state would immediately affect your object as well.

By setting the prototype to a new instance of an object, you gain access to the correct inheritance chain, but with a new, clean instance that isn't being shared with any other implementation.

See this for more.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
1

Can I just do Object.setPrototypeOf(Teacher, Person.prototype)?

No, it would have to be

Object.setPrototypeOf(Teacher.prototype, Person.prototype);

Can you use that? Yes, it's totally fine, and basically equivalent to the Object.create + .constructor definition.

So why is this not the standard approach? Mostly because Object.create was available since ES5, and Object.setPrototypeOf only was introduced with ES6, but in ES6 we would just use class Teacher extends Person anyway.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    @Loreno You might also be interested in [the even older pattern from ES3](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here) that worked in a similar manner to `Object.create` – Bergi Aug 16 '20 at 15:51