Question

I'm subclassing Array using prototype, in this way:

MyArray = function()
{
   Array.apply(this, arguments);
};

MyArray.prototype = new Array();

All works fine as expected and I can initialize a "MyArray" instance in this way:

var arr = new MyArray();
arr.push(1, 2, 3);

the problem is that fast enumeration is broken for MyArray instances, in fact the following loop:

for (var i in arr)
{
   console.log(i);
}

prints: 0, 1, 2, length

In practice every method/property of the class is included in the enumeration. In a normal array the code would print only 0, 1, 2 (those numbers are the indexes of the array).

So... my question is: how can I extend Array by preserving fast enumeration?

ps: In Objective C in order to implement fast enumeration you have to override a method... is there a special method to override in JavaScript?

Notes: obviously my real implementation of "MyArray" is slightly different, but the code I posted is enough to generate an abnormal fast enumeration loop. Don't ask me why I'm extending Array, I have my valid reasons ;)

Was it helpful?

Solution

Array elements should NEVER be enumerated with for (var x in obj) because that iterates enumerable properties of the object not just array elements which, as you can see, can include things besides array elements. Furthermore, this method of iterating is NOT guaranteed to return properties in any given order so your array elements might not be in the right order.

In the latest browsers, you can create properties with the Object.defineProperties() method and specify whether a property is enumerable or not, but that still doesn't mean it's ever correct to enumerate the elements of an array with for (var x in obj). One should always use this type of form to iterate array elements: for (var i = 0, len = arr.length; i < len; i++) or a built-in iterator like array.forEach(callback [, thisArg]).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top