This post was published on Tuesday 22nd of May 2007.
When I first read that associative arrays are supposedly evil and that one should use plain vanilla Objects in stead I was of the opinion that this was another example of JavaScript purist zealotry. Recently, I've seen the light however and I figured out some of the arguments.
First of all, just a quick recap on what an associative array is.
// This is a regular, 'indexed' array:
var a = new Array();
a.push('hello');
a.push('world');
alert(a[1]); // alerts 'world'
// This is an associative array:
var a = new Array();
a['hello'] = 'world';
alert(a['hello']); // alerts 'world'
Some of you may think the same thing I thought before: "What could possibly be the harm of using the second method?" It clearly has its uses; sometimes you'd rather use a 'string index' or hash to access a value. This is what I believe to be the issue: You are not actually creating an associative array, there's no such thing, really, in JavaScript. What you are actually doing is assigning new, custom, properties to an empty Array instance. You could do the same with a String or Number instance or any other instance of any other JavaScript object type:
var s = new String(); s['hello'] = 'world'; alert(s['hello']); // alerts 'world' alert(s.hello); // alerts 'world'
The first consequence is that if you choose a non-vanilla object type (like array), you get a couple of nonsensical methods and properties thrown in for free. Consider this:
var a = new Array(); a['hello'] = 'world'; alert(a['hello']); // alerts 'world' alert(a['length']); // alerts 0 var b = a.pop(); // no error
They won't really get in your way, even in a for-in loop but they're there nonetheless. If that idea bothers you there's the Object constructor to deliver you nuthin' but your personally defined properties (and methods).
var o = new Object(); o['hello'] = 'world'; alert(o['hello']); // alerts 'world'
Of course you can use the { name:value } shorthand too.
While the previous consequence was rather theoretical the biggest complaints are caused by something very practical: people prototyping new properties and (usually) methods to native object types.
Array.prototype.doSomething = function() {
return this.join(' - ');
}
var a = new Array();
a['hello'] = 'world';
for(var i in a) {
alert(i); // alerts 'doSomething' and 'hello'
}
Obviously this is not really desirable behavior. Even though it is possible to distinguish properties from methods things can get ugly quickly.
The bottom line is: I should have figured this out long ago like so many others did. I still believe it's completely OK to use arrays or even strings in this way, as long as you're careful. It's just that there's not really a reason for choosing the Array constructor over Object. We just have to let go of the concept 'associative array' in JavaScript. There's no such thing, like there's no 'associative boolean' or 'associative string'.
Even though I used to think that people complaining about associative arrays were just being, well, annoying I have to agree. Although associative arrays are not 'evil' and (heaven forbid) definitely not 'harmful' I certainly do not recommend their use anymore. I'll probably stop using them too. Better late than never.
Have something to say about this post? Share your thoughts!
This post was published on Tuesday 22nd of May 2007. The previous entry was "Acoustic hiphop covers". The next entry is "Canvas function plotter".