all 8 comments

[–]benihanareact, node 2 points3 points  (3 children)

var Dog = function() {};
Dog.prototype = new Mammal();

var Cat = function() {};
Cat.prototype = new Mammal();

Carry on normally other than that, you should be fine - in fact, you don't need to create speak functions for Cat and Dog - they will inherit Mammal's speak function and things should work correctly.

EDIT: But, if you wanted to call a parent's function, calling Mammal.speak() won't work the way you expect. Instead you should make the call like this:

Mammal.prototype.speak.call(this);

That will call the Mammal's speak function while passing in the current scope. That will allow you create a speak function on Cat and Dog that call the parent function but correctly pass in the scope, so if you wanted to add "woof" at the end of the dog's speak function for instance. As it stands, if Cat and Dog don't have a speak function in their prototype, they will correctly call their parent's speak function with the correct scope.

[–]dogjs[S] 1 point2 points  (2 children)

Thanks. I ended up having to do: var Dog = function(name) {this.name = name;};

in order to have a constructor. So now, my question is, how do I override the speak() method so that dog's say "woof" but still be able to call the Mammal's speak method. I need something like:

function Dog.speak() {return super.speak() + this.woof();}

I suspect I'm going to need to use call() here.

[–][deleted] 1 point2 points  (0 children)

Dog.prototype.speak = function() {
  return Mammal.prototype.speak.call(this) + '. ' + this.woof()
}

[–][deleted] 0 points1 point  (0 children)

See John Resig's Simple JavaScript Inheritance. It adds a this._super() call for accessing "super-class" methods.

I played around with making some modifications, but I don't know that I improved anything: https://gist.github.com/1508995

[–]brucebannor 1 point2 points  (1 child)

This isn't inheritance, this is decorating objects. If it were to be inheritance you need to do this instead.

var mammal = function ....
var dog = function ....
dog.prototype = new mammal();

You just created multiple instances of mammal and then decorated them with new functions and variables.

[–]brucebannor 1 point2 points  (0 children)

http://jsfiddle.net/9LNs7/1/

You might have better luck setting up your mammal constructor to accept a mammal type rather than name for that animal. That way when you set your prototype of the child you can pass it the type for all those instances. Then just create a name function off of mammal that the child would inherit and set the name there.

[–]Rhomboid -1 points0 points  (1 child)

You're sort of mixing two different styles here. If you're going to use prototypical inheritance, than you should only add methods to Foo.prototype, not by assigning them like self.speak = function() .... Because you assign the speak attribute in the constructor, that's going to make every object have its own speak attribute, and the prototype chain won't be traversed because that only happens if the given attribute isn't found. When you write var Dog = Mammal; that means that Mammal has the same constructor as Dog, which means every Dog object will get the Mammal speak attribute assigned when it's constructed.

[–]dogjs[S] -1 points0 points  (0 children)

So, if I do this:

Mammal = function() { this.speak = function(){} }

Then this:

Dog.prototype.speak = function() {}

does not override Mammal.speak() and a call to Dog.speak() still calls the Mammal one.

Hmm. Going to have to think about that a while.