JerryMan228
JerryMan228

Reputation: 35

JS: Why do you need to reset the constructor back after inheriting another prototype?

In the example below, why is Dog.prototype.constructor = Dog needed? I under we use: Dog.prototype = Object.create(Animal.prototype) to inherit the sayAnimal() and any other functions added to the Animal prototype but how does that effect the constructor? What would leaving it out do?

function Animal(gender) {
    this.gender = gender;
}

Animal.prototype.sayAnimal = function() {
    return "I am an animal"
}

function Dog(gender, barkSound) {
    Animal.call(this, gender)
    this.barkSound = barkSound
}

Dog.prototype = Object.create(Animal.prototype) 

Dog.prototype.constructor = Dog 

Upvotes: 0

Views: 324

Answers (2)

Scott Marcus
Scott Marcus

Reputation: 65806

Dog.prototype = Object.create(Animal.prototype) 

Causes the entire prototype object to be replaced with a new instance of Animal.prototype, which is important so that you don't start off with an Animal.prototype instance that has been altered from the original definition. At this point, if you were to create a new Dog, the Animal constructor would fire off and you wouldn't gain any of the characteristics of a Dog in your new instance, you'd just have another Animal.

But, when you add this:

Dog.prototype.constructor = Dog 

You are only replacing the constructor portion of the Animal.prototype, so that now when you create a new Dog, you are making a new instance of an Animal first, but with the Dog constructor, so that your Animal can be enhanced and worked with as a more specific type.

I've written a bit more about this here.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370789

Users of classes will expect the .constructor property of instances to refer to the constructor of that instance. For example:

class ExtendedArray extends Array {
}

const e = new ExtendedArray();
console.log(e.constructor === ExtendedArray);

If you're using functions and extending manually, then if you don't set the constructor property on the subclass prototype explicitly, the .constructor will refer not to the subclass constructor (as a user of the code would usually expect), but to the superclass:

function Animal(gender) {
}
function Dog(gender, barkSound) {
    Animal.call(this, gender)
}
Dog.prototype = Object.create(Animal.prototype)

// oops, this refers to Animal...
console.log(Dog.prototype.constructor);

That said, it probably isn't an issue in most situations.

Upvotes: 1

Related Questions