Javascript Associative Arrays considered harmful

Via ajaxian - looks like I need to refactor some of my code…

In Javascript, you can treat any object as an associative array, similiar to a Map or Hash structure in other languages. So its just a set of key/value pairs - in JS you can add any arbitrary property on the fly. The below example is using an Object, but you could use an Array or RegExp or FooType.

var hardcoreBands = new Object();
hardcoreBands["mathyGoodnes"] = “Dillinger Escape Plan”;
hardcoreBands["legendary"] = “Converge”;
hardcoreBands["fashionistas"] = “Every Time I Die”;for(description in hardcoreBands) { // print out the bands with descriptions
alert(hardcoreBands[description] + ” == “ + description);
}

Andrew Dupont has an insightful post warning against the use of the javascript Array type for associated arrays, when a simple Object would be better. He says:

In JavaScript, one really ought to use Object for a set of key/value pairs. But because Array works as demonstrated above, JavaScript arrays (which are meant to be numeric) are often used to hold key/value pairs. This is bad practice. Object should be used instead.

He argues that since Arrays (the big “A” type) in JavaScript are meant to represent numerically indexed things, using them as an associative array violates the principle of least surprise. Array.length doesn’t count properties added in the above manner. so the above example would return 0. The Array constructors also don’t allow for string keys, further demonstrating that they are really meant for numeric indexes.

The other problem with using Arrays as associative arrays means you can no longer extend Array.prototype, which is what Prototype 1.5 does to great effect. Prototype did break Object associative arrays in 1.4 with additions to Object.prototype, something that is fixed in 1.5 after much wailing and gnashing of teeth. Some might argue extending any of the built-in objects’ prototypes is bad form, but those people are wrong.

So use Object for associative arrays, and use Array for numeric arrays. Of course, there will always be exceptions, “no best practices”, yadda yadda - but just be aware of the danger and possible confusion if you do violate this.