Daniel Coffman
Daniel Coffman

Reputation: 2005

Trying to understand inheritance in JavaScript -- what's going on here?

Why does this say "Animal" instead of "kitty"?

// create base class Animal
function Animal(animalType) {
    this.type = animalType;
    this.sayType = function () {
        alert(this.type);
    };
}

// create derived class Cat
function Cat(myName) {
    Animal.call(this, "cat"); // cat calls the Animal base class constructor

    this.name = myName;

    this.sayName = function () {
        alert(this.name);
    };
}

Cat.prototype = Object.create(Animal); // set Cat's prototype to Animal

// instantiate a new instance of Cat
var cat = new Cat("kitty");

cat.sayName();
cat.name = "lol";
cat.sayName();

http://jsfiddle.net/dgcoffman/MguUA/5/

Upvotes: -1

Views: 100

Answers (2)

Pointy
Pointy

Reputation: 413712

You're calling Object.create() in a way that does something different than what I bet you think it does. Try this change:

Cat.prototype = Object.create(new Animal);

The Object.create() function expects its first argument to be the object to be used as the prototype for the returned object. When you pass in the function name "Animal", that means you want the prototype object to be that function object, and not an object constructed by the function.

edit — Bergi's answer involving the direct use of the Animal prototype probably makes more sense, though from what you posted there isn't an Animal prototype object with anything interesting on it. Perhaps that's elsewhere in your code, or will be added later. Anyway if it does exist it's better to do as in his answer.

Since your "Cat" constructor is picking up the "sayType" property from the Animal constructor directly, it's not clear what you're trying to do by setting the Cat prototype.

Upvotes: 1

Bergi
Bergi

Reputation: 664365

Object.create(Animal); // set Cat's prototype to Animal

Yes, but to the Animal constructor function (or, to be exact: to a new object inheriting from that function object - check the docs for Object.create). That's hardly what you want - and explains your curious result of saying "Animal", as that's the Animal function's name property.

Instead, you want to build a prototype chain, so that cat instances inherit from Cat.prototype which inherits from Animal.prototype (which inherits from Object.prototype):

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

Also, for prototypical inheritance, you should but the sayName and sayType methods on the prototype object (and only once):

Animal.prototype.sayType = function() {
    alert(this.type);
};
Cat.prototype.sayName = function() { // after creation of that object, of course
    alert(this.name);
};

Upvotes: 4

Related Questions