1

I'm just learning about prototypal inheritance and am a little confused about the use of Object.create(). I'm confused about why Object.create() is needed in the following code:

function Mammal (name){
  this.name = name;
  this.offspring = [];
}

Mammal.prototype.haveBaby = function (){
  var baby = new Mammal('Baby ' + this.name);
  this.offspring.push(baby);
  return baby;
}

function Cat (name, color){
  Mammal.call(this, name);
  this.color = color;
}

Cat.prototype = Object.create(Mammal.prototype);

Does function Cat(name, color){ Mammal.call(this, name) } not pass the on the methods from Mammal? Is that why we need Object.create()?

Liv Marx
  • 305
  • 1
  • 6
  • 12
  • 1
    No, calling the other constructor only runs the initialization code in that constructor. It does not affect the prototype chain. The technical reasons for preferring `Object.create()` to effect inheritance are pretty complicated; suffice to say that doing it that way is a Really Good Idea. – Pointy Jul 03 '18 at 12:54
  • Not related to your question, but did you realise your cat objects produce non-cat offspring? – trincot Jul 03 '18 at 15:38

1 Answers1

0

Object.create was introduced with v1.8.5 as an alternative way to specify the prototype of an object. The actual difference in the above code is that it's a bit cleaner because the Mammal constructor isn't called redundantly when setting the prototype.

You can get the same output in the above pattern using the syntax:

Cat.prototype = new Mammal();

But here the new keyword will invoke the constructor redundantly, because

Mammal.call(this, name);

then explicitly invokes Mammal again with this set to the Cat instance. So that sets name and offspring on the Cat instance (not the prototype). It's a kind of super constructor pattern as per this classical inheritance example.

The prototype chain makes haveBaby() available to all Cat instances and all Mammal instances. The only real difference is the intermediate Mammal instance vs empty object in that chain.

robC
  • 2,592
  • 1
  • 23
  • 28
  • 1
    Redundantly? I would say *incorrectly*. `Object.create` is not just an alternative, it's the only way to do it right. – Bergi Jul 03 '18 at 15:31
  • This debate may help clarify the implications... https://stackoverflow.com/a/12705137/1622684 – robC Jul 04 '18 at 08:56
  • 1
    @Bergi not disagreeing with you... the comments there contain most of the relevant issues. I didn't actually realise it was a strong point of contention. – robC Jul 04 '18 at 09:33