[javascript] Does JavaScript guarantee object property order?

Property order in normal Objects is a complex subject in Javascript.

While in ES5 explicitly no order has been specified, ES2015 has an order in certain cases. Given is the following object:

o = Object.create(null, {
  m: {value: function() {}, enumerable: true},
  "2": {value: "2", enumerable: true},
  "b": {value: "b", enumerable: true},
  0: {value: 0, enumerable: true},
  [Symbol()]: {value: "sym", enumerable: true},
  "1": {value: "1", enumerable: true},
  "a": {value: "a", enumerable: true},
});

This results in the following order (in certain cases):

Object {
  0: 0,
  1: "1",
  2: "2",
  b: "b",
  a: "a",
  m: function() {},
  Symbol(): "sym"
}
  1. integer-like keys in ascending order
  2. normal keys in insertion order
  3. Symbols in insertion order

Thus, there are three segments, which may alter the insertion order (as happened in the example). And integer-like keys don't stick to the insertion order at all.

The question is, for what methods this order is guaranteed in the ES2015 spec?

The following methods guarantee the order shown:

  • Object.assign
  • Object.defineProperties
  • Object.getOwnPropertyNames
  • Object.getOwnPropertySymbols
  • Reflect.ownKeys

The following methods/loops guarantee no order at all:

  • Object.keys
  • for..in
  • JSON.parse
  • JSON.stringify

Conclusion: Even in ES2015 you shouldn't rely on the property order of normal objects in Javascript. It is prone to errors. Use Map instead.