0

How do I get the last line to work?

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

Animal.prototype.speak = function(){
    alert('Hi, I\'m ' + this.name);
}

function Dog(name){
    this.name = name;
}

Dog.prototype.bark = function(){
  alert('Woof!');  
};

var fido = new Dog('Fido');
fido.bark(); // Woof!
fido.speak(); // Hi, I'm Fido *can't get this to work*
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124

3 Answers3

7

You need to set the Dog prototype to a new Animal.

Dog.prototype = new Animal();
maerics
  • 151,642
  • 46
  • 269
  • 291
  • Do I need to set Dog.prototype.constructor = Dog; – KingKongFrog Nov 20 '13 at 21:35
  • @KingKongFrog: for your use case you do not need to; however, doing so might be a good idea in case other code checks that property for type identification. In practice I've never seen an important reason to do so. – maerics Nov 20 '13 at 21:41
  • this is where my main confusion is. Why/when do I have to set the prototype.constuctor ? – KingKongFrog Nov 20 '13 at 21:42
  • @KingKongFrog: that is a totally different (and totally valid) question. – maerics Nov 20 '13 at 21:43
  • 1
    This is not a good idea too use an instence of the parent object has prototype. The parent must be constructible without parameter. And the constructor may certainly do useless operation for prototype declaration. – Techniv Nov 20 '13 at 21:47
1
...
function Dog(name){
    this.name = name;
}

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

Dog.prototype.bark = function(){
    alert('Woof!');  
};
...

Object.create create a new empty object and use the parameter has prototype of this object.

You can make a inheritence in the constructor too:

function Dog(name){
    Animal.call(this, name);
    this.name = name;
}

Here, you call the Animal constructor on the new Dog context.

Techniv
  • 1,967
  • 15
  • 22
  • In this specific exemple the inheritence in the constructor is a little bit useless. – Techniv Nov 20 '13 at 21:41
  • 1
    In this specific example it's actually super useful. It demonstrates how instance specific member `name` gets initialized as instanceOfDog.name when you create it. `this.name=name` is no longer needed in Dog because Animal already does that. If you have a whole bunch of values that need to be validated and set then one line in Dog, Cat, Bird ... would take care of that. – HMR Nov 21 '13 at 05:46
1

In short; you can do it like this:

var Dog = function(name){
  //re use Animal constructor
  Animal.call(this,name);
  //you can do Animal.apply(this,arguments); as well
};
//set up the prototype chain
Dog.prototype = Object.create(Animal.prototype);
//repair the constructor property
Dog.prototype.constructor = Dog;

An introduction to constructor functions, inheritance and prototype can be found here.

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160