2012-09-25 50 views
2

我想在Javascript中實現一個集合 - 有無論如何實現我的集合中的元素數組索引器?如何在Javascript中實現類似數組的索引器([])?

到目前爲止,我有以下代碼:

var Collection = function() { 

    var collection = []; 

    var addAccessor = function(api, name) { 
     if (toString.call(collection[name]) == '[object Function]') { 
     api[name] = (function(){ 
      return function() { 
      return collection[name](arguments); 
      }; 
     }()); 
     } 
     else { 
     Object.defineProperty(api, name, { 
      get: function() { return collection.length; }, 
      enumerable: true, 
      configurable: true 
     }); 
     } 
    }; 

    var publicApi = {}; 

    var methods = Object.getOwnPropertyNames(Array.prototype); 
    for(var i = 0, len = methods.length; i < len; ++i) { 
     var method = methods[i]; 
     addAccessor(publicApi, method); 
    } 

    return publicApi; 
    }; 
}; 

所有的Array.prototype方法和屬性達到預期效果。

var c = Collection(); 
c.push(4); 
console.log(c.length); // 1 

但有一件事我無法弄清楚是怎麼得到以下工作:

console.log(c[0]);  // should print 4, currently undefined 

反正有沒有做到這一點?

+1

你不能。任何具體的原因你不只是使用'數組'? – jbabey

+0

我認爲你的代碼中缺少一些東西。 'collection'永遠不會被填充,所以沒有Array原型被複制。你可以發佈一個工作小提琴嗎? – David

回答

2

如果你想 「擴展」 陣,經典的方法是這樣的:用new

Collection.prototype.color = function() { 
    this.push('color'); 
}; 

並使用它::

function Collection(){}; 
Collection.prototype = new Array(); 
Collection.constructor = Collection; 

現在添加您自己的方法

var myArray = new Collection(); 
myArray.push(1); 
myArray.color(); 

如果你想添加一個新的push訪問Array推送的方法,請嘗試:

Collection.prototype.push = function() { 
    console.log('pushed!'); 
    Array.prototype.push.apply(this, [].slice.call(arguments)); 
}; 
+0

這是我開始的地方,但後來我需要在一些Array方法上引發事件。在這種情況下,我將如何重寫'Collection.prototype.push',以便我可以在將元素推入數組的同時執行自己的代碼? – Bill

+0

@Bill看我的編輯。 – David

+0

'Array.prototype.push.apply(this,[] .slice.call(arguments));'導致堆棧溢出。 – Bill