Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

This proposal has been accepted and merged into the main specification. This repository exists only for historical interest.

Specifying for-in enumeration order


ECMA-262 leaves the order of for (a in b) ... almost totally unspecified, but real engines tend to be consistent in at least some cases. Furthermore, over the years implementations have observed that anyone who wants to run code on the web needs to follow some constraints not captured by the spec.

This is a stage 4 (finished) proposal to begin fixing that.


Historical efforts to get consensus on a complete specification of the order of for-in have repeatedly failed, in part because all engines have their own idiosyncratic implementations which are the result of a great deal of work and which they don't really want to revisit.

See the exploration directory for background and test cases from before this was a concrete proposal.

A conservative underapproximation of interop semantics

From this list of interop semantics we can derive a conservative underapproximation of cases where engines already agree, which I believe covers the most common common cases. Specifically:

  • Neither the object being iterated nor anything in its prototype chain is a proxy, typed array, module namespace object, or host exotic object.
  • Neither the object nor anything in its prototype chain has its prototype change during iteration.
  • Neither the object nor anything in its prototype chain has a property deleted during iteration.
  • Nothing in the object's prototype chain has a property added during iteration.
  • No property of the object or anything in its prototype chain has its enumerability change during iteration.
  • No non-enumerable property shadows an enumerable one.

All but the last are fairly easy to specify in prose; the last is somewhat harder. As far as I know JavaScriptCore is the only engine which will output anything in this case, because of this longstanding bug, so I am hopeful that point can be discarded.


There are a variety of APIs which make a property enumeration order observable. for-in is the most complex, because it, uniquely, enumerates properties from the prototype chain as well. The remaining can be split into those which use the same order as for-in does for own properties, which are affected by this proposal, and those which use the same order as Reflect.ownKeys, which are not.

for-in-ordered APIs

The following APIs use EnumerableOwnPropertyNames, which requires that its results be ordered "in the same relative order as would be produced by the Iterator that would be returned if the EnumerateObjectProperties internal method were invoked with [the object in question]". EnumerateObjectProperties is the spec-internal method which is used by for-in, and is the part of the spec which this proposal is concerned with improving.

The other-effects directory contains tests demonstrating simple examples of how each of these are observable. All major engines already agree in all of these cases.

Because all of the objects produced by JSON.parse are within the interop semantics, it will be fully specified after this proposal. The others can all be passed exotic arguments and so will not.

Reflect.ownKeys-ordered APIs

The following APIs invoke the [[OwnPropertyKeys]] internal method directly, whose behavior is fully specified. They are therefore not affected by this proposal.

Spec text

See candidate spec text. This does not yet capture the "no non-enumerable property shadows an enumerable one" constraint above, because I am having trouble figuring out how to say that.


Partially specifying object enumeration order in JavaScript






No releases published


No packages published