Prototype vs. Web 2.0
Array type for associative arrays.
Object is an associative array or hash table. An
Array is also an
Object (in fact,
typeof  == 'object'), but it’s really meant for arrays indexed by integers.
It’s an easy mistake to make, especially for someone who has come from a language where the associative array type is called an array. I don’t think I’ve made this particular mistake, but I have made a similar one. I used to use the
for-in loop because I liked its simplicity:
That looks better to me than the C-style loop:
for-in loop works on an
Array because an
Array is an
Object, but that also means it treats the
Array as an
Object. It enumerates the array elements because they are also properties of the underlying
Object, but it doesn’t necessarily enumerate them in order by index:
In the browsers I tried, this code alerts the letters in the order that they were added to the array, not in index order. But there’s no guarantee about that order either, because the
for-in loop doesn’t promise any particular order of enumeration.
for-in also enumerates any extra properties or methods added to the array:
This alerts the source code for the
alert method as well as the three letters in the array, because they are all properties of the underlying
The same thing happens if the
alert method is added via
And that’s where we get into trouble with Prototype, because it adds methods to
Array.prototype. This breaks any code that uses
for-in on an
Array. But as we just discussed, no one should do that, so it won’t be a problem in any properly-written code. Right? Case closed.
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.
I wouldn’t argue that it’s bad form, but extending the native object prototypes causes real pain for two groups of people:
It’s that whole Web 2.0 mashup thing, you know?
for-in loop on an array—“correct” or not. Or code that uses some other library that also extends
Array.prototype—even a different version of Prototype that conflicts with mine.
I love the good taste of syntactic sugar as much as anyone, and if it didn’t break other code I’d be merrily adding methods to the native objects too. But I have to make my code compatible not only with the code I control, but the code I don’t. So it’s no Prototype for me.