javamonkey79
javamonkey79

Reputation: 17775

Javascript prototypal inheritance weirdness

I'm trying to work through some javascript inheritance examples and I hit a wall with this one:

function Animal(){}
Animal.prototype.type = "animal";
Animal.prototype.speak = function(){ console.log( "I'm a " + this.type + 
    ". I can't really talk ;)" ); }

function Dog(){}

function F(){}
F.prototype = Animal.prototype;

Dog.prototype = new F();
Dog.prototype.constructor = Dog;
Dog.prototype.type = "Dog";
Dog._super = Animal.prototype;
Dog.woof = function(){ console.log( "Woof!" ); _super.speak(); }

var rover = new Dog();
rover.woof();

I am getting this and I have no idea why:

TypeError: Object #<Dog> has no method 'woof'

I know I can put the not-found method into the constructor function, but I am trying to do this with prototype modification. What am I doing wrong here?

Upvotes: 3

Views: 302

Answers (5)

Sandeep Nair
Sandeep Nair

Reputation: 1

//Rewrote the code to make it work

function Animal(){}
Animal.prototype.type = "animal";
Animal.prototype.speak = function(){ console.log( "I'm a " + this.type + 
    ". I can't really talk ;)" ); }

function Dog(){}
function F(){}

F.prototype = Object.create(Animal.prototype); //F inherits from animal
Dog.prototype = Object.create(F.prototype);    //Dog inherits from F

Dog.prototype.constructor = Dog; //resetting the constructor to Dog object
F.prototype.constructor=F;       // resetting the constrctor to F object 

Dog.prototype.type = "Dog";

Dog.prototype.woof = function(){ console.log( "Woof!" ); this.speak(); } //adding woof method to the prototype of dog

const rover = new Dog();

rover.woof();

// output
// Woof!
// I'm a Dog. I can't really talk ;)

Upvotes: 0

NullUserException
NullUserException

Reputation: 85468

Change:

Dog._super = Animal.prototype;
Dog.woof = function(){ console.log( "Woof!" ); _super.speak(); }

To:

// Dog.prototype._super = Animal.prototype; <- you can remove this line
Dog.prototype.woof = function(){ console.log( "Woof!" ); this.speak(); }

Upvotes: 4

Gopherkhan
Gopherkhan

Reputation: 4342

So your woof method is actually effectively a static method (If you're coming from java. Basically, it's hanging off the Dog function, and can be accessed without an instance of Dog. ie: Dog.woof())

To get it working with an instance of a dog, you want to make sure it's a prototype definition (again, with a Java analogy, effectively a instance method definition). As qwertymik said,

Dog.prototype.woof = function(){ console.log( "Woof!" ); this.speak(); }

Then you'll be able to do

var foo = new Dog();
foo.woof();

Upvotes: 3

qwertymk
qwertymk

Reputation: 35274

Maybe you mean to do this:

Dog.prototype._super = Animal.prototype;
Dog.prototype.woof = function(){ console.log( "Woof!" ); this._super.speak(); }

Upvotes: 1

bjornd
bjornd

Reputation: 22943

The last string of the Dog pseudo-class definition is wrong. It should be

Dog.prototype.woof = function(){ console.log( "Woof!" ); Dog._super.speak.call(this); }
  1. You should define method woof as the property of the Dog's prototype.
  2. _super is available only as the property of the Dog constructor.
  3. You should call the methods of the parent class in context of the current instance.

Upvotes: 4

Related Questions