Unexpected loop behavior in Javascript
Published on the 24th of January 2012Yesterday I found out another bug involving my "favorite" browser...
Internet Explorer 8, perhaps also 7, behaves a lot differently when doing a for in loop on a array compared to the modern browsers.
Basically the thing I wanted to do was dynamiclly fill an array with elements using a predefined order.
The resulting array would look a lot like this:
var names = []; names[0] = "0. John"; names[1] = "1. Mary"; names[3] = "3. Jack"; names[4] = "4. Jane";
The thing is I couldn't control the order in which elements would be added to the array.
So the order in which elements would be added could easily look a lot like this:
var names = []; names[3] = "3. Jack"; names[1] = "1. Mary"; names[4] = "4. Jack"; names[0] = "0. John";
Now here is the thing. Since you have blank keys in the array you can't use a regular for loop.
In the example above names[2] isn't defined which prevents you from creating a basic:
for(var i=0;i<names.length;i++){}
The easiest way to iterate through such a incomplete array is by using a for in loop like so:
for (var key in names) { var name = names[key]; if (typeof(name) === "function") continue; document.write(name + '\r\n'); }
This however produces unexpected resuls in IE8.
In Chrome, Safari, Firefox and IE9 it would output:
0. John 1. Mary 3. Jack 4. Jane
In IE8 this produces:
3. Jack 1. Mary 4. Jane 0. John
As you might notice IE iterates through the elements of the array by the order in which they were added.
How to fix this unexpected behavior?
The simplest solution is to simply copy the array before iterating like so:
// IE fix names = names.slice(); for (var key in names) { var name = names[key]; if (typeof(name) === "function") continue; document.write(name + '\r\n'); }
This will reorder all array elements accordingly.
I've created a small snippet to see the bug and fix in action on jsfiddle.
