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);
4 Answers 4
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.
4 Comments
Object.create(Person) does not return a call- or construtable Object, so for Teacher = Object.create(Person) a new Teacher() throws a TypeError: Teacher is not a constructor and as of that it just does not work.Teacher a constructor. You must first define Teacher as a constructor function before you can adjust its prototype property like that. For instance var Teacher = function() {}... and then the Teacher.prototype = ... will work.When you create a new instance with your constructor, e.g.
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.
4 Comments
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
3 Comments
let foo = 1; foo = 2; we lose the 1 value.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
new Teacherinstance. How should that look?classkeyword with much cleaner syntax for doing all this, but really I think it's best to stay away from trying to use class-based code at all in JS. (Because it's not a class-based language, even the ES6classis just syntactic sugar.)