3

I saw a question about the iteration order of for...in statements, and warning that the order cannot be trusted. How is the iteration and tracking of the current and visited nodes done internally, and how does it differ among JavaScript engines?

Paul Sweatte
  • 22,871
  • 7
  • 116
  • 244
  • This related post might provide some insight http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop – lostsource Nov 19 '12 at 20:40

2 Answers2

3

From the MDN documentation for for...in (emphasis added):

Iterates over the enumerable properties of an object, in arbitrary order.

I'm sure that the internal details vary among JavaScript engines, and most likely even among versions of any particular engine. My guess that in many engines, it's done through some sort of hash table implementation. Since hash functions will reorder keys as the hash table grows, the relative order of, say, properties a and b can change just by adding a new property c, without changing engines or anything.

Ted Hopp
  • 222,293
  • 47
  • 371
  • 489
0

It seems that the implementation of Object.keys() and Object.defineProperties should mimic the behavior of for...in:

If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used in step 5 of this algorithm.

so they can be used for reference.

The delete operator can also complicate things:

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.

as can name clashes in the prototype chain:

Enumerating the properties of an object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively; but a property of a prototype is not enumerated if it is “shadowed” because some previous object in the prototype chain has a property with the same name. The values of [[Enumerable]] attributes are not considered when determining if a property of a prototype object is shadowed by a previous object on the prototype chain.

References

Paul Sweatte
  • 22,871
  • 7
  • 116
  • 244