1

Order.assign() change object order. I pas

{val: 1, ts: 2}

I get

{ts: 2, val: 1}

In my app all tied to the keys, and key order is important. What do& Help..

luanped
  • 2,838
  • 2
  • 21
  • 35
ZPPP
  • 1,499
  • 2
  • 14
  • 25
  • Nooo. Its error in my example – ZPPP Dec 30 '15 at 22:26
  • 3
    There is no such thing as order in JS objects. It's not guarantied, so don't rely on it. – dfsq Dec 30 '15 at 22:26
  • http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – epascarello Dec 30 '15 at 22:27
  • one of the biggest popular misconceptions about JS engines is that they don't order objects. was ES3/5 vague? sure. is the spec vague now? no. do any engines randomly re-order keys? no. how does the spec define order? like V8 has done for years. – dandavis Dec 30 '15 at 22:28
  • tommorow's sun rise is "not guarantied", but does that affect it's actual reliability? – dandavis Dec 30 '15 at 22:47
  • @dandavis Even if the spec did enforce an order based on when properties are added and removed from the object, that would still make any code that relies on their order would be fragile; since objects can be serialized and deserialized and their properties are recreated in implementation-defined order by the deserializer. Javascript already has a built-in data structure for ordered lists called arrays; and robust code that relies on ordering, uses them. – Paul Dec 30 '15 at 23:01
  • @Paul 5 years later, the order is still preserved: if I assign 2 properties to an object, they will be read in the same order if I do object.keys. it's scary that it'll change in future but to rewrite code into arrays is just annoying if it's working right now. – zavr Mar 17 '20 at 18:52
  • @zavr Object keys don't have an order, so "same order" is meaningless – Paul Mar 17 '20 at 19:04
  • yes it is meaningful as i described because in whatever order i ADD items to the object, in the same order they will be returned from Object.keys. so they do have an order – zavr Mar 17 '20 at 19:05

1 Answers1

4

Javascript objects keys are unordered by definition (See https://stackoverflow.com/a/32149345/772035), so key order cannot be important. If the order that keys are displayed in or visited in when iterating is causing problems, then your app has a bug that needs fixing.

Usually you just need to restructure your data so that you have an array instead of an object, since arrays have guaranteed order in Javascript.

Community
  • 1
  • 1
Paul
  • 130,653
  • 24
  • 259
  • 248
  • 1
    that's not true anymore in the spec (by definition), and hasn't been true in practice ever (save a few weeks that chrome broke it about 5 years ago) – dandavis Dec 30 '15 at 22:26
  • @dandavis interesting - do you know which spec version? – Dominic Dec 30 '15 at 22:29
  • 1
    @dandavis Can you point me to the spec where that has been changed. As far as I know it is still implementation dependent, and the only requirement is that `Object.key` returns the keys in the same order as a `for...in` loop visits them. I think if they did change it that was a big mistake, as code that relies on key ordering would almost always be better off using a normal array anyway. – Paul Dec 30 '15 at 22:30
  • 1
    @dandavis Do you have a reference from the spec? That article doesn't reference it at all, and when I look at the ES6 script the order you described is only required for `[[OwnPropertyKeys]]()`. `[[Enumerate]]()` is required to return the same keys as `[[OwnPropertyKeys]]()`, but not in a specific order. In fact the spec is quite clear that the order is not specified: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-enumerate – Paul Dec 30 '15 at 22:52
  • @dandavis See this answer for a complete list of the ways in Javascript where order is guaranteed: http://stackoverflow.com/a/32149345/772035 . Anywhere else (for...in, Object.keys, etc.) it is still implementation defined, and code that relies on it is inherently broken. – Paul Dec 30 '15 at 23:06
  • @Paulpro: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys makes it clear: numerical keys are sorted, rest are insertion-order; agreed? – dandavis Dec 30 '15 at 23:06
  • @dandavis That's the same spec I linked to. That order is defined for `[[OwnPropertyKeys]]()` like I said, but not for `[[Enumerate]]()`. – Paul Dec 30 '15 at 23:07
  • @Paulpro: yes, but "[[Enumerate]] must obtain the own property keys of the target object as if by calling its [[OwnPropertyKeys]] internal method.", so they are the same really... – dandavis Dec 30 '15 at 23:08
  • @dandavis Yes, it has to iterate through the same set of keys as `[[OwnPropertyKeys]]()` returns, but it doesn't have to go through them in the same order, hence the "as if". The spec clearly says "The mechanics and order of enumerating the properties is not specified" – Paul Dec 30 '15 at 23:09
  • @dandavis See this for more info: https://esdiscuss.org/topic/property-ordering-of-enumerate-getownpropertynames – Paul Dec 30 '15 at 23:11
  • hmmm. perhaps for enumeration (custom/for-of) that's the case, but for Object.keys(), JSON, for-in and other "legacy" iteration, OwnPropertyKeys's order is specified. that could make `for-of` faster in the future, so that makes sense... – dandavis Dec 30 '15 at 23:14
  • @dandavis `Object.keys` and `for-in` both use `[[enumerate]]()` The only case where the order is guaranteed is when calling `Object.getOwnPropertyNames`, `Object.getOwnPropertySymbols`, or `Reflect.ownKeys`. – Paul Dec 30 '15 at 23:17
  • @Paulpro: maybe we are assuming different meanings for "as if". the spec could be clearer, even still.... do you have a fiddle that demonstrates a different ordering in Object.keys() than 9.1.12 dictates? – dandavis Dec 30 '15 at 23:24
  • @dandavis It is quite clear what the "as if" means if you read the last post on this link: https://esdiscuss.org/topic/property-ordering-of-enumerate-getownpropertynames . No I can't show you a fiddle, because most implementation will just call `[[OwnPropertyKeys]]()` in their implentation of `[[Enumerate]]` and not bother to reorder them to some other ordering. However, just because every engine I know of is doing it the same way, does not mean that code should really on that undefined behaviour, which could change at any time (and results in lower quality code even when it works). – Paul Dec 30 '15 at 23:30
  • 1
    I think focusing on the minutiae of what the spec says misses the obvious point to be made. Even if some order is specified by the spec or can generally be relied upon in modern JS engines, you *should not* do it anyway, as code that relies on such ordering is going to be unclear to a reader whose mental model of objects is an unordered collection of key-value pairs. – Tim Destan Dec 30 '15 at 23:40
  • hopefully ES7 will remove all doubts and help foster a more realistic mental model. – dandavis Dec 31 '15 at 01:50
  • @dandavis Yeah, it would be nice if they avoid ambiguity. Personally I would rather see them enforce a random order than a well-defined one; but my preference would be for them to go back to how it was in the ES5 spec , which made it very clear that object's keys are unordered. – Paul Dec 31 '15 at 02:22