If I create an object like this:
var obj = {}; obj.prop1 = "Foo"; obj.prop2 = "Bar";
Will the resulting object always look like this?
{ prop1 : "Foo", prop2 : "Bar" }
That is, will the properties be in the same order that I added them?
YES (but not always insertion order). Most Browsers iterate object properties as: Integer keys in ascending order (and strings like "1" that parse as ints) String keys, in insertion order (ES2015 guarantees this and all browsers comply) Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)
To illustrate that JavaScript object keys are not ordered, let's compare them to an array: a simple list of items in a specific order. JavaScript arrays have a defined order from index 0 to the last item in the list, and items added to the array using . push() stay in the order they are added in.
The order of properties in an object depends on the type of the included properties and their values. Looking at the spec the rules are defined in the internal "ownPropertyKeys" method. Which is used for example by fairly new methods Object. getOwnPropertyNames and Reflect.
In short, Yes.
The iteration order for objects follows a certain set of rules since ES2015, but it does not (always) follow the insertion order. Simply put, the iteration order is a combination of the insertion order for strings keys, and ascending order for number-like keys:
// key order: 1, foo, bar const obj = { "foo": "foo", "1": "1", "bar": "bar" }
Using an array or a Map
object can be a better way to achieve this. Map
shares some similarities with Object
and guarantees the keys to be iterated in order of insertion, without exception:
The keys in Map are ordered while keys added to object are not. Thus, when iterating over it, a Map object returns keys in order of insertion. (Note that in the ECMAScript 2015 spec objects do preserve creation order for string and Symbol keys, so traversal of an object with ie only string keys would yield keys in order of insertion)
As a note, properties order in objects weren’t guaranteed at all before ES2015. Definition of an Object from ECMAScript Third Edition (pdf):
4.3.3 Object
An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.
YES (for non-integer keys).
Most Browsers iterate object properties as:
Some older browsers combine categories #1 and #2, iterating all keys in insertion order. If your keys might parse as integers, it's best not to rely on any specific iteration order.
Current Language Spec (since ES2015) insertion order is preserved, except in the case of keys that parse as integers (eg "7" or "99"), where behavior varies between browsers. For example, Chrome/V8 does not respect insertion order when the keys are parse as numeric.
Old Language Spec (before ES2015): Iteration order was technically undefined, but all major browsers complied with the ES2015 behavior.
Note that the ES2015 behavior was a good example of the language spec being driven by existing behavior, and not the other way round. To get a deeper sense of that backwards-compatibility mindset, see http://code.google.com/p/v8/issues/detail?id=164, a Chrome bug that covers in detail the design decisions behind Chrome's iteration order behavior. Per one of the (rather opinionated) comments on that bug report:
Standards always follow implementations, that's where XHR came from, and Google does the same thing by implementing Gears and then embracing equivalent HTML5 functionality. The right fix is to have ECMA formally incorporate the de-facto standard behavior into the next rev of the spec.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With