原型继承,为什么一个实例而不是原型?

时间:2010-12-06 10:11:10

标签: javascript prototype

我一直想知道,因为我学习了原型继承,为什么要将父类的实例推送到子原型而不是原型本身?

var Animal = function(type){
    this.type = type;
}
Animal.prototype.getType = function(){
    return this.type;
}
var Cat = function(options){
    this.breed = options.breed;
}

//Inheritance
Cat.prototype = new Animal('Cat');

为什么不这样做继承?

Cat.prototype = Animal.prototype;

我的猜测是,只继承原型,你不包括在构造函数(this.type)中创建的属性,但我不完全确定。有人想开导我吗?

但是,不是将一个实例放入子类原型中,而是将所有构造函数定义的属性放入原型中,从而引入可能的陷阱?我正在考虑这样一个事实:除非在构造函数中定义了原型属性,否则它们将在类的所有实例之间共享。

2 个答案:

答案 0 :(得分:18)

好吧,如果不考虑它,如果采用后一种方法,那么原型链实际上就不会持有。例如,我们假设Animal继承自Entity。然后Animal.prototype某些指向Entity的指针 - 然后

Cat.prototype = Animal.prototype;

会将Cat的原型设置为与相同的原型(即一些实体引用)。这样可以使Cat成为动物的兄弟,而不是按照预期使孩子

因此,为了正确建立原型链,必须使用父类的实例,以便能够获取该类的属性。

答案 1 :(得分:4)

危险!!!

如果您分配原型然后它们是同一个对象,对Cat.prototype的任何更改都将修改Animal.prototype

function Animal() { }
function Cat() { }
Cat.prototype = Animal.prototype;
Cat.prototype.legs = 4;
console.log(new Animal().legs + "!!"); // 4!!

更新

顺便说一下,要做一个完整的继承,你还必须继承构造函数,在父代内部调用它:

function Animal() {
    this.onDie = new Signal();
}
function Cat() {
    Animal.call(this);
   // do your stuff here...
}
Cat.prototype = new Animal();

如果没有,你将无法获得构造函数在这种情况下作为“onDie”注入实例的属性。