Iterating a JavaScript array the safe way

JavaScript itself does not provide a control structure to loop through an array (e.g. foreach in Perl or PHP), you may use the for statement to iterate over all elements of an array. (Notice that JavaScript does not support named keys with arrays thus use Object instead.)

The for … in statement is a special case of the for statement. It is used exclusively to walk through arrays and objects. In the case of arrays, it allows you to step through each array element. […] The benefit of this statement is that to you would otherwise have to determine the number of elements in an array or object before you could use a for statement.

As Peter L. Kantor in JavaScript: Iteration writes just simple iterate the array with for ... in statement and there you are. In the most cases it works but there is a lion in the way. When you define methods to the Array object itself, although array.length will not count them, they will appear inside the for ... in statement. You may test this behaviour easily with Firebug.


>>> Array.prototype.toJSONString = function() {}
>>> var arr = [];
>>> arr.length
0
>>> arr[0] = "Software is like sex";
"Software is like sex"
>>> arr.length
1
>>> arr
["Software is like sex"]
>>> for (key in arr) { console.log(key); }
0
toJSONString

When walking through an object, the for … in statement will not step through every property. It will only step through those that are defined as enumerable. In other words, it will only step through those those are defined as properties that can be counted by JavaScript iterative processes. […] System-defined methods are not enumerable, though most system-defined properties are. User defined properties are always enumerable.

And that’s the answer to our question. Always enumerable. So you cannot rely on for ... in statement unless you are sure that no third-party library will add properties or methods to the Array class and even you will not do so.

The solution hence is to use a for statement like this: for (key = 1; k < array.length; k++) { };. That’s all now folks.