我对原型继承的概念比较新,所以也许这就是原型继承应该如何工作,或者这可能只是javascript但看起来像原型继承只是很好的主要类型。例如,我有以下代码:
var leg = {
type: null
};
var Animal = {
traits: {},
leg: Object.create(leg)
};
var lion = Object.create(Animal);
lion.traits.legs = 4;
lion.leg.type = 'left';
var bird = Object.create(Animal);
bird.traits.legs = 2;
bird.leg.type = 'right';
alert(lion.traits.legs) // shows 2???
alert(lion.leg.type) // shows right???
最后两行显示我的困惑。这真的是原型继承应该如何工作,还是这就是javascript如何实现它?
如果这真的是原型继承应该如何工作,我真的不知道这种类型的继承在大多数情况下是如何有用的。如果我只能有原始类型,那么创建复杂对象似乎非常有限,因为在很多情况下我有一个对象存储另一个对象的实例。
答案 0 :(得分:2)
不要继承非原始状态。继承方法。使每个对象都有自己的状态。状态是使对象唯一的原因,如果所有对象共享相同的状态,则没有意义。
var Animal = {
method1: function() {},
method2: function() {}
};
var lion = Object.create(Animal, {
traits: {
value: {}
},
leg: {
value: {
type: null
}
}
});
var bird = Object.create(Animal, {
traits: {
value: {}
},
leg: {
value: {
type: null
}
}
});
顺便说一句,对于做同样的事情,有一个更简洁,更好的支持语法:
function Animal(traits, leg) {
this.traits = traits;
this.leg = leg;
}
var method = Animal.prototype;
method.method1 = function() {
};
method.method2 = function() {
};
var lion = new Animal({}, {type: null}),
bird = new Animal({}, {type: null});
答案 1 :(得分:0)
是,这是应该如何运作的。属性traits
和leg
是可变对象,它们在实例之间共享。原型继承的想法是你从原型继承所有状态,除非你明确地覆盖它。您不会覆盖字段trait
和leg
,因此它们会与原型共享。
这与基于类的继承不同,其中state永远不会被继承,您必须初始化构造函数中的所有状态。
你可以拥有复杂的对象,但如果每个实例都需要拥有自己的对象字段的新实例,则必须在创建实例后创建它们,就像在构造函数中一样。
原型继承很有用(与基于类的继承相比),因为:
您可以节省大量内存,因为您只为与原型不同的字段分配“插槽”。在基于类的对象中,您总是必须为所有字段分配空间,即使它们永远不会从默认值更改。
继承更改很容易。例如。例如,如果您在UI框架中有一个“窗口”原型,并且从该原型继承了许多具体窗口,您可以更改原型上的颜色,并自动继承到未明确覆盖它的所有实例。 / p>