javascript中的继承问题
我有以下类层次结构:javascript中的继承问题,javascript,inheritance,Javascript,Inheritance,我有以下类层次结构: 储藏 收藏 EixoCollection 收藏指南 我有以下代码: var ofertaCollection = new OfertaCollection(); var eixoCollection = new EixoCollection(); ofertaCollection.set('mykey', 'myvalue'); alert(eixoCollection.get('mykey')); // it returns 'myvalue', shoul
- 储藏
- 收藏
- EixoCollection
- 收藏指南
- 收藏
var ofertaCollection = new OfertaCollection();
var eixoCollection = new EixoCollection();
ofertaCollection.set('mykey', 'myvalue');
alert(eixoCollection.get('mykey')); // it returns 'myvalue', should return nothing
问题是OferTocollection和eixoCollection具有相互引用的属性
遵循以下课程:
/**
* Storage
*
* @returns {Storage}
*/
function Storage(){
this.storage = []; // itens that have a key
// sets key
this.set = function(key, value){
this.storage[key] = value;
}
// gets key
this.get = function(key){
return this.storage[key];
}
}
/**
* Collection
*
* @returns {Collection}
*/
function Collection(){
}
Collection.prototype = new Storage();
/**
* EixoCollection
*
* @returns {EixoCollection}
*/
function EixoCollection(){
}
EixoCollection.prototype = new Collection();
/**
* OfertaCollection
*
* @returns {OfertaCollection}
*/
function OfertaCollection(){
}
OfertaCollection.prototype = new Collection();
问题是什么?问题是两个收集对象共享同一个
存储对象
var c1 = new OfteraCollection().prototype.prototype;
var c2 = new ExioCollection().prototype.prototype;
console.log(c1 === c2); // true
要解决这一问题,您可以将集合
全部丢弃,让每个集合对象创建自己的存储
作为其原型。首先,我建议对代码进行两个更改(示例将使用):此。存储
应该是一个对象{}
,因为看起来你从来没有把它用作数组。另外,get
和set
应该在原型中,否则将为每个实例对象创建这些方法的新实例(除非智能编译器对它们进行优化,但我们不会假设太多)
解决方案1:您可以执行准继承,这样只有您的存储方法被赋予继承类,而不是存储对象:
解决方案2:真正的继承,但为每个集合实例化一个新存储,因此在原型查找过程中,函数会找到本地存储。这与上面的相同,但继承将与以前一样。因此,我将替换不同的行:
Collection.prototype = new Storage(); // real inheritance
这两种实现的问题在于,它们要求继承类做两件事,既继承方法,又实例化存储。不漂亮
最简单的选择,也可能是最直观的选择,就是使存储的每次使用都成为一个复合对象,而不是继承对象。一个集合有一个内部存储器和一些额外的功能,因此它满足了has-A助记符的要求,使合成成为一个有效的候选者。这里有一个非常快速的解决方案-更改:
function Collection(){
// assuming you're doing some initialization here, referencing "this"
}
Collection.prototype = new Storage();
到
或者,如果不进行任何初始化,只需:
function Collection(){
return new Storage();
}
这将Collection
转换为Storage
工厂,从而防止在子体中重用相同的Storage
对象。为什么还要使用Collection
类?在我看来像是严重的肿胀。。。你所做的只是包装存储
类。我修改了我的答案,但我仍然很好奇。你为什么这么做?你有其他方法来处理你的对象吗?在我看来,你真正需要做的就是说var coll=newobject();coll[键]=值代码>是的,我有。我只展示了缩小代码=)的方法。我不明白修正后的答案,你能举个例子吗?(js=p中的新手)我现在不能,但在此同时阅读:不确定“创建他们自己的存储
作为他们的原型”是什么意思。如果你所做的只是删除集合
层,那么每种类型(如果它将其原型实例化为新存储()
)仍然会受到共享内存问题的影响,一种类型的多个实例是不独立的。
function Collection(){
var that = new Storage();
// initialize whatever's necessary, using "that"
return that;
}
function Collection(){
return new Storage();
}