pmuellr is Patrick Mueller, Senior Node Engineer at NodeSource.

other pmuellr thangs: home page, twitter, flickr, github

Tuesday, April 14, 2009

ordered javascript properties

So all this time, I believed what I had read regarding the ordering of properties when enumerating JavaScript objects with the statement, with this being a typical description:

A loop iterates over the properties of an object in an arbitrary order.

That's from the Mozilla Developer Center JavaScript reference.

Turns out that's not quite true. See John Resig's blog post "JavaScript in Chrome", and scroll down to the section "for loop order". In particular, John writes: "All modern implementations of ECMAScript iterate through object properties in the order in which they were defined. Because of this the Chrome team has deemed this to be a bug and will be fixing it." Follow the links to the bugs John points out in his blog post for more discussion.

I couldn't resist trying this out myself, so created a little test case, here. WebKit Nightlies and FireFox 3.0 behave the same for all the cases, but Opera 9.23 acts a little differently in one of the cases.

John makes a couple of points I can't agree with, in his comments in the Chromium bug that he referenced.

  • The specification does not define how an implementation should handle it - therefore an implementation should conform with other implementations.

    What? How does not having an explicit definition in the spec imply that all implementations should conform with each other?

  • The argument that they're doing it to "keep the engine fast and lean" is bogus. There are two other, faster, ECMAScript engines out there: SquirrelFish and TraceMonkey and they both implement the looping indentically.

    John is referencing a previous comment which claimed that V8 did not respect the 'definition order' because doing so could impact memory usage and/or peformance. But the rationale John makes is that since there are two faster engines which DO implement the 'definition order', the memory/performance rationale is bogus. Which makes no sense of course. I would imagine the typical implementation of 'definition order' would trade space over speed, so you could make the property access "fast enough" by spending some additional space to maintain the order as well as the presumably speedy hash access. Complete guess on my part. But to me, it's hard to imagine that implementing 'definition order' isn't going to cost you SOMEWHERE, over not implementing it. I'm cheap, I don't like to pay for things I don't need.

So not only was I surprised by the property ordering, I'm kind of sad because it means JavaScript has some built-in waste for a feature few objects will probably ever need. Kind of like Java's monitors in every object. Ah well.

A few folks pointed out to me that upcoming EcmaScript standards would likely standardize on this ordering behavior. While it's difficult (for me anyway) to track down EcmaScript standard stuff, I did find this set of drafts which seemed ... recent ... and looking at the "23 Feb 2009" version, you can see phrases like "An ECMAScript object is an unordered collection of properties" (page 14) have been changed to "An ECMAScript object is a collection of properties". Hardly a ringing endorsement of defined property ordering, but a step in that direction, no doubt.

So, I guess change is coming. Next question, how can we make use of this?

One thought is with JSON. Typically with JSON you think of object definitions with key/value properties, all defined "at once". Meaning things like "streaming" JSON objects don't really make sense. Only now, maybe it kinda does. Or you could do something like add a property to an object first, called something like "__type__" which would provide some shape information, which a serializer could make use of, because it would see that before other properties.

That's nice. And is fairly logical. But the memory/performance impact will probably always bug me.