JS inheritance - MDN article

164 Views Asked by At

given MDN JS Inheritance article, we have these lines

enter image description here

My question is, why use Object.create and not just Person.prototype? I understand the need to link prototypes. But here is console example rendering the call to Object.create in fact not connecting the inherited methods: enter image description here

Why is that? is it mistake in the article?

2

There are 2 best solutions below

1
On

The problem with Teacher.prototype = Person.prototype is that then, there is no actual inheritence going on - both prototypes will reference the same object. If you proceed to add a function to Teacher's prototype, for example getClassTaught(), that will mutate Person.prototype, which should not have that method.

function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() { return this.name; };
function Teacher(name, className) {
  this.name = name;
  this.className = className;
}
Teacher.prototype = Person.prototype;
Teacher.prototype.getClassTaught = function() { return this.className; };

const person = new Person();
console.log('getClassTaught' in person);

You also wouldn't be able to shadow Person functions without replacing them entirely. For example, if there's a greeting() function on Person.prototype, and you assign another greeting() function to Teacher.prototype, you'll be overwriting the function on Person.prototype - other persons calling greeting() may not work anymore, because the function is now Teacher-specific, rather than Person-generic.

function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() { return this.name; };
Person.prototype.greeting = function() { return 'Hi, I am ' + this.name; };
function Teacher(name, className) {
  this.name = name;
  this.className = className;
}
Teacher.prototype = Person.prototype;
Person.prototype.greeting = function() { return 'Hi, I am Teacher ' + this.name; };

const person = new Person('Bob');
console.log(person.greeting());

getOwnPropertyNames only shows you the property names directly on the object itself - it does not show inherited property names. When you use Object.create(Person.prototype), greeting is inherited from the Person prototype; it's not directly on Teacher.prototype, so it doesn't show up in getOwnPropertyNames.

0
On
 Teacher.prototype = Person.prototype

That sets the prototye of the teachers to the same object as the persons prototype. So if you change that:

Teacher.prototype.hi = () => alert("hi");

Then that exists both on teachers and persons:

new Person().hi();

Thats not what you want when creating a subclass. If you do

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

You create a new object that inherits the persons prototype. Now the properties do not exist on the object itself, but they are inherited. That getOwnPropertyNames returns nothing does not mean that the properties are not inherited but the opposite: They just don't exist on the object itself, but on its parent.

 new Teacher().greeting();  // works :)