0

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 

2 Answers2

1

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.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • thanks. At first, I thought it would create problems creating new instances of `Dog` but since `Dog` uses `Dog.constructor`, that hasn't changed...what would be using `Dog.prototype.constructor` ? – JerryMan228 Feb 02 '21 at 20:31
  • The user of an instance, when it's not sure what it's an instance of. It can use the `.constructor` property of the instance to get to the constructor function. This situation is extremely unusual in my experience, I've never encountered a need for it (outside of silly things like JS trivia questions) – CertainPerformance Feb 02 '21 at 20:36
0
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.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71