Stumbled across this one recently. Stumbled as in I fell down, grazed my knees, and couldn’t get up properly for a couple of hours. Turns out that arrays in Javascript can have a length that is totally utterly wrong. 😦
I had some fairly neat code to build a DHTML tree control dynamically. I built up a tree object, with each level of the tree represented as an array. Each node had an id, and this meant I could write code like this:
var tree = createTree(); tree.createNode("1", "Tree Root"); tree.nodes["1"].createNode("11", "Node Label");
Works well, and everything was dandy. Until I tried some node ids that were not converted numbers.
What I found can best be expressed using the following lines of code as an example:
var arr; arr = new Array(); alert("length = " + arr.length); // length = 0 arr["1"] = "foo"; alert("length = " + arr.length); // length = 2 arr = new Array(); arr["50"] = "bar"; alert("length = " + arr.length); // length = 51 arr = new Array(); arr["wibble"] = "wobble"; alert("length = " + arr.length); // length = 0
My code was detecting if there were any leaves at a given level by asking (inside a “hasChildren()” method) what the length was; a non-zero answer meant there were children. The length wasn’t used for iterating the array, but merely for checking to see if it was non-empty.
Alas, as the above code demonstrates: when using a string for the array ‘index’ (which is legal in IE and FireFox, at least), the length property doesn’t get increased. How utterly, totally shitty.
Five hours of annoying debugging and perplexed bemusement later, I add one line of code; I increment the length of the child array by 1 when I insert a new child. (This was a slightly safer fix than adding a ‘hasChildren’ property). Problem solved.
Updated: The example now uses strings for the index of the array to better illustrate the problem.