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();
}