4

I don't remember where, but I once saw it put that for..in loops can go through the elements in any order the implementors like, including forward, backward, randomly, or alternating between forward and back for each execution of a for..in loop. In practice, though, somehow I don't think that the latter is really the case with any implementation in existence. (Although, there is a certain browser we know who likes to mess things up, so you can never be too sure, but I digress.)

My point is that while there probably isn't such bad deviation in for..in sequencing in practice, I'd like to know what deviation, if any, there is between ECMAScript implementations. I suppose the main ones now would be JScript, Chakra, Futhark, Carakan, JavascriptCore, SquirrelFish, V8, SpiderMonkey, and TraceMonkey, just for reference.

tckmn
  • 57,719
  • 27
  • 114
  • 156
wwaawaw
  • 6,867
  • 9
  • 32
  • 42
  • 4
    If the language specification says that the ordering is not guaranteed, that means that any of the implementations could change its mind *tomorrow*. The right thing to do is write code that doesn't depend on things that can't be depended on. – Pointy Nov 18 '12 at 14:17
  • 1
    For reference, i pretty much made that exact statement in http://stackoverflow.com/a/10587330/319403 :) – cHao Nov 18 '12 at 16:41
  • @cHao Guess that's where I saw what I was referring to, then. Thanks! :) – wwaawaw Nov 19 '12 at 09:11

1 Answers1

5

First of all, here's a reference from the specification with regard to the order of enumeration:

12.6.4 The for-in Statement

The mechanics and order of enumerating the properties (step 6.a in the first algorithm, step 7.a in the second) is not specified. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.

The only ones I can think of off hand are these:

  • Earlier (maybe current?) versions of IE would place new properties that were added during enumeration to the end of the enumeration so that they would be visited by the current running for-in

  • V8 has a different order of enumeration as described in this bug report, which was closed as WorkingAsIntended

     var a = {"foo":"bar", "3": "3", "2":"2", "1":"1"};
    

    Testing in Firefox and V8 show a different order.

This is not much of a list. There certainly may be more. I think it is summed up by @Pointy's comment. There's no guarantee. Even if you have an object that reliably enumerates in a consistent manner, this doesn't mean that it will do so with the next version upgrade. Use tools for how they're specified to work, not for what merely seems to work.

Community
  • 1
  • 1
I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
  • Thanks for the, ummm, constructive answer! I think it's so unconstructive to just close a question without even actually reading it. – wwaawaw Nov 19 '12 at 09:24
  • 1
    You're welcome. I'm not sure how question is it "not constructive" either. It certainly seems valid to ask whether or not there are actual variations in practice, and whether or not one should rely on the `for-in` ordering when it does seem to work. Any such list could quickly become obsolete, but the core question stays relevant. – I Hate Lazy Nov 19 '12 at 12:17
  • The question boils down to "When/to what degree can i ignore the spec"? The obvious answer is "Never; specs are there to be followed". Any other answer is going to be subjective and highly debatable, not to mention time-specific. – cHao Nov 19 '12 at 14:25
  • 1
    @cHao: There are often details in implementations of a specification that are uniform irrespective of inclusion in the specification. Sometimes these uniformities eventually become included. So it's worth asking. – I Hate Lazy Nov 19 '12 at 14:32
  • It's worth asking if you're on the ommittee rewriting the spec. It's not worth it for someone who wants to write non-crappy code. – cHao Nov 19 '12 at 14:34
  • 1
    @cHao: Did you ever use `.innerHTML` before it was included in HTML5? – I Hate Lazy Nov 19 '12 at 14:35
  • Yeah, i used it back in like the NS4 and IE6 days, because i didn't know any better. Back then, i even used for...in with arrays. Then i learned it was non-standard, and *stopped*. The fact that i once did it too doesn't make it any less wrong. – cHao Nov 19 '12 at 14:42
  • @cHao: The mere fact that it wasn't part of a specification doesn't make it objectively wrong. If it's reliably present in the implementations you support, then why not use it? *(I generally don't use it, but that's because I favor DOM manipulation methods. But that's beside the point.)* – I Hate Lazy Nov 19 '12 at 14:50
  • @user1689607: Because the very phrase "the implementations you support" is rather wrongheaded. It's only a half step removed from the bad old days of the browser wars, when every site was like "Requires Netscape Navigator" or "Best viewed in Internet Explorer". No. It's HTML and Javascript -- if done correctly, it should work pretty much *everywhere*. And if it doesn't, you're the one that looks incompetent, cause everyone else manages to do it. :) – cHao Nov 19 '12 at 15:22
  • @cHao: Yes, but by "everywhere", you actually mean all the major implementations, right? I mean I doubt that you scour the earth looking for and testing every possible implementation in existence. *I certainly hope not anyway. ;-)* So if that's the case, then you can just as well substitute "everywhere" for "in the implementations you support" in my previous comment. – I Hate Lazy Nov 19 '12 at 15:25
  • I mean every implementation that adheres to the spec. Major, minor, doesn't matter. There could be some i-just-threw-it-together-for-a-homework-assignment browser, and as long as it respects the spec, stuff should work on it. If it doesn't, i don't care *what* it supports. Just like if i'm writing a browser, and some code uses stuff that's explicitly *not* in the spec, *i don't have to care whether that code works*. The whole point of the standards is to establish expectations, and any expectations outside the spec are unwarranted. – cHao Nov 19 '12 at 15:29
  • @cHao: So you simply write code that adheres to the spec, even if some major implementation doesn't? In other words, you don't utilize any fixes for non-compliant implementations? Yes, stuff *should* just work, but then we wake up. :-) – I Hate Lazy Nov 19 '12 at 15:32
  • @user1689607: Stuff *does* just work, in like 97% of all cases. And where it doesn't, there's another standard way that does. Or it's something you shouldn't be freaking doing in the first place. :) – cHao Nov 19 '12 at 15:34
  • @cHao: Yes, very much of it does just work. It's the 3% that requires compromise of our standards. :) Anyway, I think we know where each other stand by now. Thanks for the discussion. :) – I Hate Lazy Nov 19 '12 at 15:41