Javascript For...in
This is a short note on a baffling bit of javascript behaviour concerning the for...in loop. The otherwise excellent W3Schools writes:
The for...in statement is used to loop (iterate) through the elements of an array or through the properties of an object.
And gives the following example of its use:
var x;
var mycars = new Array();
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
for (x in mycars)
{
document.write(mycars[x] + "<br />");
}
Looks just like a slightly unwieldy for-each loop, right? Well not according to Mozilla. In their excellent Developer centre they write about the for...in loop that
Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea. The for...in statement iterates over user-defined properties in addition to the array elements, so if you modify the array's non-integer or non-positive properties (e.g. by adding a "foo" property to it or even by adding a method or property to Array.prototype), the for...in statement will return the name of your user-defined properties in addition to the numeric indexes. Also, because order of iteration is arbitrary, iterating over an array may not visit elements in numeric order.
In other words, because it iterates over every property name in an object using the method to iterate over an array will return all the array values plus any other properties the array object might have, including prototype methods and properties.
Now since there's a billion libraries out there all happily adding their prototypes to native javascript objects it is very likely that using the for...in construct to iterate over an array can give unexpected results.
Here's an example
In the following bit of code I've extended that Array object with a new method and then rerun the W3Schools code:
// Returns true if this array contains 'needle'
Array.prototype.contains = function(needle)
{
var i;
for (i=0; i<this.length; i++) if (this[i] == needle) return true;
return false;
}
var mycars = new Array("Saab", "Volvo", "BMW");
var x;
for (x in mycars) document.write(mycars[x] + "<br />");
Running this in firefox 3 gives the following results:
Saab
Volvo
BMW
function (needle) { var i; for (i = 0; i < this.length; i++) { if (this[i] == needle) { return true; } } return false; }
Not what the doctor ordered!
Now going by Mozilla's interpretation of the for...in method this all makes perfect sense. But it still leaves me with two questions:
- Why would anyone want to do this?
- Is there a real for-each loop in javascript?
Any input would be greatly appreciated.
Mar 15th, 2009
Comments
Limhes wrote:
Hoe is 't in Israel btw? Jahaha, ik weet alles :)
Apr 27th, 2009
Michael wrote:
nice!
Apr 22nd, 2009
Limhes wrote:
By the way, it works! You have to get the value out of the returned Array(key, value) however..
Apr 21st, 2009
Limhes wrote:
You could try:
for (x in Iterator(mycars))Muhahaha{
document.write(x[1] + <br />);
}
Apr 21st, 2009
If you wish to add code to your comment you can use code tags, like this: <code class="php">yourCodeHere</code>.
Quite a large number of languages are supported, although I can't guarantee it'll be pretty. Inside the code tags you can use any characters except for the string "</code>".