2

I noticed that the ECMAScript definitions for Objects have changed from the 3rd edition to the 5th and 6th.

3rd edition

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.

5th and 6th edition

4.3.3
object
member of the type Object.
NOTE An object is a collection of properties and has a single prototype
object. The prototype may be the null value. 

Since it no longer says an unordered collection of properties, does that mean they are ordered now? and for JavaScript too?

Marco Chan
  • 53
  • 5
  • No, that does not mean they are ordered, there's still no order in objects – adeneo Dec 08 '15 at 19:59
  • It's in the specs, [here](http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4), *"The mechanics and order of enumerating properties is not specified."*. – adeneo Dec 08 '15 at 20:02
  • 1
    @adeneo Note that that ES5 rule has been superseded by the ES6 rule of `[[OwnPropertyKeys]]`, which provides specific rules for property enumeration order. (Whether that's been *implemented* is another story, of course.) – apsillers Dec 08 '15 at 20:09
  • @apsillers - indeed, it seems ES2015 has some implied order based on insertion, but we're still a long way from being able to rely on it. – adeneo Dec 08 '15 at 20:41
  • @apsillers: No it's still in the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-enumerate . – Felix Kling Dec 09 '15 at 00:33
  • @FelixKling Neat! I see now from the duplicate that I also misunderstood `[[Enumerate]]`'s dependency on `[[OwnPropertyKeys]]` (i.e., it does not preserve order). – apsillers Dec 09 '15 at 02:01
  • @adeneo I was wrong! `:O` – apsillers Dec 09 '15 at 02:01

1 Answers1

3

Sort-of, at least in the sixth edition (emphasis mine):

9.1.12 [[OwnPropertyKeys]] ( )

When the [[OwnPropertyKeys]] internal method of O is called the following steps are taken:

  1. Let keys be a new empty List.
  2. For each own property key P of O that is an integer index, in ascending numeric index order

    a. Add P as the last element of keys.

  3. For each own property key P of O that is a String but is not an integer index, in property creation order

    a. Add P as the last element of keys.

  4. For each own property key P of O that is a Symbol, in property creation order

    a. Add P as the last element of keys.

  5. Return keys.

The specification relies on the insertion order of properties, implying that the order must be part of the object. It also specifies that for in loops must use this order (see 7.3.21 and 19.1.2.14). However, browsers do not entirely respect this in all cases, so you shouldn't rely on it.

The ES6 Map type also specifies insertion order for iteration. I believe that this case is respected by all browsers, so you should prefer it if you need to rely on this behaviour.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • 1
    Notice that this only defines an order for `Object.getOwnPropertyNames`, not for `for … in` loops or `Object.keys` as one might have expected. – Bergi Dec 08 '15 at 20:57
  • And of course, you should *never* rely on it. If you need a collection with defined order, use a `Map`. – Bergi Dec 08 '15 at 20:58
  • @Bergi Hmm... I'm not sure I'm parsing this right, but I think that for-in uses [[Enumerate]] which uses [[GetOwnPropertyKeys]], which enforces this order for properties that are coming from the same object. The spec says "the order is not specified", but its requirements do seem to require this order... I guess it could meant that it needs to obtain the keys using [[GetOwnPropertyKeys]]'s approach, but the implementation is free to return them in a different order. In any case, yes, use a `Map`. (edit: I see you've discussed this specifically in the duplicate target.) – Jeremy Dec 08 '15 at 21:29
  • *"I guess it could meant that it needs to obtain the keys using [[GetOwnPropertyKeys]]'s approach, but the implementation is free to return them in a different order."* Yes. That was clarified in https://esdiscuss.org/topic/property-ordering-of-enumerate-getownpropertynames . – Felix Kling Dec 09 '15 at 00:37
  • @FelixKling Thanks for the link. – Jeremy Dec 09 '15 at 00:38
  • @JeremyBanks Would it then be possible to shuffle the order of a Map? – Marco Chan Dec 09 '15 at 01:17
  • @MarcoChan You'd need to remove and re-insert every element, in the new order. – Jeremy Dec 09 '15 at 03:02