Someone asked me recently, are JavaScript object properties necessarily unordered and unpredictable?

Developers with early exposure to JavaScript might answer that `Object.keys()` or `for...in` returns an unpredictable order of object properties. But is that still the case?

As you might expect, there are now rules to follow.

Starting with ECMAScript 2020, `Object.keys`, `for...in`, `Object.getOwnPropertyNames`, and `Reflect.ownKeys` all follow the same order of specification. They are:

## 1. Own properties are array indexes, in ascending numeric index order

![JavaScript object property order example showing array index keys in ascending numeric order](https://img.upweb.dev/content/86c52d44-800x449.png)

An array index is a String-valued property key that is a canonical numeric String. And a [canonical numeric String](http://www.ecma-international.org/ecma-262/10.0/) is a String representation of a number that would be produced by `ToString`, or the string "-0". So for instance, "012" is _not_ a canonical numeric String, but "12" is.

## 2. Other own String properties, in ascending chronological order of property creation

![JavaScript object property order example showing string keys in chronological creation order](https://img.upweb.dev/content/de86d32c-800x634.png)

The above code adds the knowledge point of the event loop. Because `setTimeout` is an asynchronous macro task, the `c` property has not been added to `obj` when `console.log` is output.

## 3. Own Symbol properties, in ascending chronological order of property creation

![JavaScript object property order example showing Symbol properties in chronological creation order](https://img.upweb.dev/content/791c3147-800x423.png)

The Symbol property is the same as the String property, in ascending chronological order of property creation. But the `Object.keys`, `for...in`, `Object.getOwnPropertyNames` methods cannot get the object's Symbol properties, `Reflect.ownKeys` and `Object.getOwnPropertySymbols` can.

## Conclusion

When an object’s property keys are a combination of the above types, the object’s non-negative integer keys (enumerable and non-enumerable) are first added to the array in ascending order, then String keys are added in insertion order. Finally, Symbol keys are added in insertion order.

![JavaScript object property order complete example combining integer keys, string keys, and Symbol keys](https://img.upweb.dev/content/4da80ea8-800x436.png)

But if you strongly depend on the insertion order, then [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) guarantees that for you.

_If you found this helpful, consider [subscribing to my newsletter](https://upweb.dev) for weekly web development insights and updates. Thanks for reading!_
