So I’ve been getting up to speed on some of the newer features of JavaScript and have been reading about Object.setPrototypeOf(). I ran across this bit of code from MDN which deals with inheriting from regular objects. But I’m confused at how they use Object.setPrototypeOf() here. I expected them to write
Object.setPrototypeOf(Dog, Animal)
as opposed to what the do below. Why do they write it this way?
var Animal = { speak() { console.log(this.name + ' makes a noise.'); } }; class Dog { constructor(name) { this.name = name; } } Object.setPrototypeOf(Dog.prototype, Animal);// If you do not do this you will get a TypeError when you invoke speak var d = new Dog('Mitzie'); d.speak(); // Mitzie makes a noise.
Advertisement
Answer
The reason for calling Object.setPrototypeOf
is to make sure that any objects created by the Dog
constructor will get the Animal
object in their prototype chain. It would be wrong to set a prototype of the constructor itself (not to be confused with the constructor’s prototype
property which really is a misnomer), since the constructor has no place in d
‘s prototype chain.
A created Dog
object does not get Dog
in its prototype chain, but Dog.prototype
. Dog
is just the vehicle by which objects are created, it is not supposed itself to become part of the prototype chain.
You could instead do this in the Dog
constructor:
Object.setPrototypeOf(this, Animal)
That makes the length of the prototype chain one step shorter, but the downside is that now d instanceof Dog
will no longer be true. It will only be an Animal
. This is a pitty, and it explains why it is good to keep the original Dog.prototype
object, while setting its prototype to Animal
, so that now d
is both a Dog
and an Animal
.
Read about this subject here. I would promote my own answer to that Q&A.