JavaScript原型继承

时间:2016-03-18 04:03:22

标签: javascript inheritance prototype prototypal-inheritance

下面是一个简单的JavaScript继承示例。我们可以替换该行:Dog.prototype = new Animal();
与Dog.prototype = Animal.prototype?

我已在浏览器中测试过,他们给了我相同的结果。我很奇怪为什么我们需要创建一个新的Animal对象并将其分配给Dog.prototype。

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

Animal.prototype.walk = function(){
     console.log("Walk"); 
}

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

Dog.prototype = new Animal();      //Why not Dog.prototype = Animal.prototype
Dog.prototype.constructor = Dog;


dog_b = new Dog("yellow", 9);
console.log("Age: " + dog_b.age +  " Color: " + dog_b.color );
dog_b.walk()

1 个答案:

答案 0 :(得分:2)

在这种特殊情况下,您可以更换线条,原因很简单:

function Dog(color, age) {
    this.color = color;
    Animal.call(this, age); // This line
}

在这里,您使用call调用Animal的构造函数,为其提供this,从而手动建立Animal的上下文。因此this内的function Animal将始终引用Dog的对象。这就是new根本无法发挥作用的原因。

严格地说,你实际上并没有做适当的原型继承。您可以通过执行以下操作确认:

dog_b.hasOwnProperty('age'); // => true

这实际上称为constructor stealing Dog窃取Animal的构造函数。 walk方法虽然位于Animal的ctor。

这意味着age属性本身位于Dog上,而不是Animal上。这是为什么?同样,因为您手动将Animal的构造函数上下文设置为Dog

修改

在Javascript中有各种描述和获得继承的方法,因为这不是写书的地方,我会很快。

您正在做的事情被称为Parasitic Combination Inheritance(您不必记住该术语)。这没有错,它只是获得继承的另一种方式(仅对于Animal.prototype上的函数是原型的)。如果它适合你,我会说它。如果您真的希望Animal的{​​{1}}位于age上,那么在使用构造函数获取继承时,您将遇到问题。

这样做的一种方法是:

Animal

如您所见,原型继承通常用于对象文字(想想angular的范围对象)。