admin管理员组

文章数量:1392116

I'm trying to implement a collection in Javascript - is there anyway to implement an array-like indexer for elements in my collection?

So far, I have the following code:

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

All of the Array.prototype methods and properties work as expected.

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

But the one thing I can't figure out is how to get the following to work:

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

Is there anyway to do this?

I'm trying to implement a collection in Javascript - is there anyway to implement an array-like indexer for elements in my collection?

So far, I have the following code:

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

All of the Array.prototype methods and properties work as expected.

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

But the one thing I can't figure out is how to get the following to work:

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

Is there anyway to do this?

Share Improve this question asked Sep 25, 2012 at 15:34 BillBill 25.6k8 gold badges99 silver badges129 bronze badges 2
  • 1 You can't. Any specific reason you're not just using an Array? – jbabey Commented Sep 25, 2012 at 15:36
  • I think something is missing in your code. collection is never populated, so no Array prototypes are copied. Can you post a working fiddle? – David Hellsing Commented Sep 25, 2012 at 15:42
Add a ment  | 

2 Answers 2

Reset to default 4

If you want to "extend" Array, the classic way would be something like:

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

Now add your own methods:

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

And use it with new:

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

If you want to add a new push method that access Array push, try:

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

using classes:

class Collection extends Array {
  color() {
    this.push('color')
  }
}

本文标签: How to implement an arraylike indexer ( ) in JavascriptStack Overflow