试图理解JavaScript中的继承 - 这里发生了什么?

时间:2013-05-02 19:44:39

标签: javascript inheritance prototype

为什么这说“动物”而不是“小猫”?

// 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/

2 个答案:

答案 0 :(得分:4)

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

是的,但是对于Animal构造函数(或者,确切地说:对于从该函数对象继承的新对象 - 检查docs for Object.create)。这几乎不是你想要的 - 并解释了你说"Animal"的好奇结果,因为那是Animal function's name property

相反,您希望构建一个原型链,以便cat实例继承自{em> Cat.prototype (继承自Animal.prototype)的Object.prototype

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

此外,对于原型继承,您应该在原型对象上使用sayNamesayType方法(并且只能使用一次):

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

答案 1 :(得分:1)

你以一种不同于我认为它所做的不同的方式来调用Object.create()。试试这个改变:

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

Object.create()函数期望其第一个参数是对象,以用作返回对象的原型。传入函数名称“Animal”时,这意味着您希望原型对象成为该函数对象,而不是该函数构造的对象

编辑 - Bergi的回答涉及直接使用Animal原型可能更有意义,尽管从你发布的内容中没有一个动物原型对象,其上有任何有趣的东西。也许这在您的代码中的其他位置,或稍后将添加。无论如何,如果它确实存在,那么最好像他的回答一样。

由于你的“Cat”构造函数直接从Animal构造函数中获取“sayType”属性,因此通过设置Cat原型不清楚你要做什么。