我有以下类层次结构:

  • 存储
  • 收藏
  • EixoCollection
  • OfertaCollection

  • 我有以下代码:
    var ofertaCollection = new OfertaCollection();
    var eixoCollection = new EixoCollection();
    
    ofertaCollection.set('mykey', 'myvalue');
    alert(eixoCollection.get('mykey')); // it returns 'myvalue', should return nothing
    

    问题是 ofertaCollection 和 eixoCollection 具有相互引用的属性。

    跟随类(class):
    /**
     * 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();
    

    问题是什么?

    最佳答案

    首先,我建议对您的代码进行两项更改(示例将使用): this.storage 应该是一个对象 {} ,因为看起来您从未将其用作数组。此外,getset 应该在原型(prototype)中,否则将为每个实例对象创建这些方法的新实例(除非智能编译器优化它们,但我们不会假设太多)。

    解决方案1:您可以执行准继承,即只有您的存储方法被赋予继承类,而不是存储对象:

    function Storage(){}
    storage.prototype = {
        get: function(key){
            return this.storage[key];
        },
        set: function(key, value){
            this.storage[key] = value;
        }
    };
    
    function Collection(){
        this.storage = {};
    }
    Collection.prototype = Storage.prototype; // quasi-inheritance
    
    function EixoCollection(){}
    EixoCollection.prototype = new Collection();
    
    function OfertaCollection(){}
    OfertaCollection.prototype = new Collection();
    
    var ofertaCollection = new OfertaCollection();
    var eixoCollection = new EixoCollection();
    
    ofertaCollection.set('mykey', 'myvalue');
    alert(eixoCollection.get('mykey')); // undefined
    

    解决方案 2:真正的继承,但是为每个集合实例化一个新的 store,所以在原型(prototype)查找过程中函数会找到本地 store。这与上面的相同,但继承会和以前一样。所以我将替换不同的行:
    Collection.prototype = new Storage(); // real inheritance
    

    这两种实现的问题在于它们需要继承类做两件事,既继承方法,又实例化一个存储。不漂亮。

    最简单的替代方法,也许也是最直观的方法是让 Storage 的每次使用成为一个复合对象,而不是一个继承对象。一个集合有一个内部存储和一些额外的功能,所以它满足了 has-a 助记符,使组合成为一个有效的候选者。

    关于javascript - javascript中的继承问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6256941/

    10-12 22:28
    查看更多