Own Property Enumeration Order

ECMAScript 5 didn’t define the enumeration order of object properties, as it left this up to the JavaScript engine vendors. However, ECMAScript 6 strictly defines the order in which own properties must be returned when they are enumerated. This affects how properties are returned using Object.getOwnPropertyNames() and Reflect.ownKeys (covered in Chapter 12). It also affects the order in which properties are processed by Object.assign().

The basic order for own property enumeration is:

  1. All numeric keys in ascending order
  2. All string keys in the order in which they were added to the object
  3. All symbol keys (covered in Chapter 6) in the order in which they were added to the object

Here’s an example:

  1. var obj = {
  2. a: 1,
  3. 0: 1,
  4. c: 1,
  5. 2: 1,
  6. b: 1,
  7. 1: 1
  8. };
  9. obj.d = 1;
  10. console.log(Object.getOwnPropertyNames(obj).join("")); // "012acbd"

The Object.getOwnPropertyNames() method returns the properties in obj in the order 0, 1, 2, a, c, b, d. Note that the numeric keys are grouped together and sorted, even though they appear out of order in the object literal. The string keys come after the numeric keys and appear in the order that they were added to obj. The keys in the object literal itself come first, followed by any dynamic keys that were added later (in this case, d).

W> The for-in loop still has an unspecified enumeration order because not all JavaScript engines implement it the same way. The Object.keys() method and JSON.stringify() are both specified to use the same (unspecified) enumeration order as for-in.

While enumeration order is a subtle change to how JavaScript works, it’s not uncommon to find programs that rely on a specific enumeration order to work correctly. ECMAScript 6, by defining the enumeration order, ensures that JavaScript code relying on enumeration will work correctly regardless of where it is executed.