Matt Snider JavaScript Resource

Understanding JavaScript and Frameworks

Tuesday, July 22, 2008

Extending Array

I have not written code extending Array yet, as I have had concerns about breaking the web while extending Array. The problem is that any changes to the prototype of Array breaks “for … in” loops. After some discussion with other JavaScript architects and further thought, it became apparent that extending Array doesn’t really break the web. First of all, the only issue is that after modifying the “Array.prototype”, using “for … in” loops on an Array returns each attached Function, as well as each member of the Array, so you would have to do what YUI does and ignore theses keys. However, you would only need to use “for … in” loops if you were creating associative arrays, and an associative Array can be represented instead with an Object, so there is no need to use them. Therefore, it is good practice to use Object in place of any associative Arrays. If you follow this practice, then one only needs to iterate numerically on an Array, never needing the “for … in” loop; allowing us to safely extend “Array.prototype” with useful methods.

The most important method is probably the “Array.get” Function attached statically to Array. This method converts Array-like objects such as ‘arguments’ and ‘collection’ to an Array, so that you get all the syntactic sugar of “array.js” on non-arrays. This is most useful in conjunction with “document.getElementsByTagName” or simply ‘arguments’.

I have also added the concept of a pointer to Array so that you can iterate through the Array with functions like: ‘next’, ‘prev’, and ‘current’, which point to the appropriate index in the Array. Some other useful short-hand methods like: ‘first’ and ‘last’ have also been added.

Beyond those, there is a slew of other useful functions, that allow for easy Array management. It is all well documented, check “array.js” out here. And I have written an array unit test here.

posted by Matt Snider at 8:49 pm  

4 Comments »

  1. Matt,

    What’s the reason for making Array.prototype.unique rely on function decomposition? This makes any non-primitive value in an array disregarded as non-unique. This doesn’t seem wise.

    [{foo: true}, {foo: false}].unique(); // [{foo: true}]

    Comment by kangax — July 23, 2008 @ 10:47 am

  2. Kangax,

    The unique method came out of a discussion with Christian Heilmann on his blog (Wait till I come). I cannot find the exact reference, so I am not sure if the article is still up.

    Anyway, you are correct that unique doesn’t handle a collection of like objects well… this would fail miserably on an array of JSON objects.

    However, it works really well on arrays of simple data. If you know of a better method, I am always open to improving code, but I am looking for simple, readable/reliable, and fast code.

    Comment by Matt Snider — July 30, 2008 @ 10:05 am

  3. First thing that comes to mind is something like:

    Array.prototype.unique = function() {
    var matches = [];
    for (var i=0, l=this.length; i

    Comment by kangax — August 1, 2008 @ 8:52 am

  4. ok, let’s try again:

    Array.prototype.unique = function() {
    var matches = [];
    for (var i=0, l=this.length; i<l; i++) {
    if (matches.indexOf(this[i]) === -1) {
    matches.push(this[i]);
    }
    }
    return matches;
    };

    Comment by kangax — August 1, 2008 @ 8:53 am

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress