简体   繁体   中英

JS prototype : Inheritance

From the given MDN Article

在此处输入图片说明

Why can't we just do the following code instead of the one given in picture , is there any difference between them?

Teacher = Object.create(Person);

Object.create creates an object which cannot be callable. Even if you pass a function (constructor) as its argument, the object that is created by Object.create will not have the internal [[Call]] property, which is what makes function objects callable. It is not inheritable via the prototype chain.

So, in short, you need to define Teacher as a constructor (or using the class syntax, which still makes it a constructor function), which is something you cannot do with Object.create .

When you create a new instance with your constructor, eg

  const teacher = new Teacher();

then JS does the following under the hood:

1) It creates a new object that inherits the constructors prototype property

2) It calls the constructor with this being the new object:

 const teacher = Object.create(Teacher.prototype); // 1
 Teacher.call(teacher); // 2

Now if you want the teacher to inherit all methods and properties of Person, you have to make Teacher.prototype inherit Person.prototype as the instances inherit that. So this:

  teacher  -> Teacher.prototype
  teacher2 ->

has to be changed to

 teacher  -> Teacher.prototype -> Person.prototype
 teacher2 ->

therefore the teachers prototype has to inherit the persons prototype.

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

The other line however:

  Teacher = Object.create(Person);

Makes little sense as that destroys the Teacher constructor, as Object.create returns an object and not a function. You could however:

 Object.setPrototypeOf(Teacher, /*to*/ Person);

Then Teacher would inherit all static properties of Person , but the instances wouldn't inherit anything, as Teacher.prototype does not inherit Person.prototype .

Teacher = Object.create(Person);

by the above line of code you are assigning a totally different value to Teacher.

Instead, you could have asked a question about the following:

Teacher.prototype = Person.prototype

but in this case also, the problem is, any change to Teacher prototype will also change the Person prototype (because they refer the same object), and that could have undesirable side-effects.

So,

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

is correct

Your question has two sub-questions.

1) Assigning Teacher.prototype vs Teacher :

let Teacher = function() { /* does something */ } // <-- the constructor

Teacher.prototype = Object.create(Person.prototype); // <-- the constructor did NOT lost 
Teacher = Object.create(Person.prototype); // <-- the constructor lost 

In the lower version you will lose the constructor of Teacher (of course if it existed). And in the upper one, you will overwrite only its prototype.

2) Assigning to Person.prototype vs Person :

Teacher.prototype = Object.create(Person); // Normally `Person` does not have any properties
Teacher.prototype = Object.create(Person.prototype); // But `Person.prototype` does.

In other words, one can very well add properties to Person, not to Prototype, but usually properties are added to Person.prototype so that they can be inherited by instances of Person .

Person.foo = function() {}
const person = new Person()
person.foo // undefined

// vs
Person.prototype.foo = function() {}
const person = new Person()
person.foo // its a function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM