2012-09-25 51 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