3

I ran into the oddest behavior while working on a ticket this morning. If you see below after running Object.keys, the order of the keys has changed leaving P after F.

I tried the following:

  • Object.entries - got the same result as Object.keys
  • For loop - got the same result as Object.keys
  • I thought perhaps that the # was throwing off the sorting, so I removed it and re ran the test. - got the same result as Object.keys

I looked at the ECMAScript spec and this should not be case. Any ideas what could be causing this behavior ?

enter image description here

P.S I fixed the issue by running .sort() on the array but was curious to know what's causing the keys to go out of order.

9
  • 5
    As far as I know, the spec does not tell anyone how to order keys. Keys are ordered by the browser in different ways. You should never rely on the order of keys, that's what an Array is for. Commented Sep 23, 2019 at 13:31
  • 2
    order of keys is not guaranteed in javasciprt, however most of the time the string keys are in order they were added in Commented Sep 23, 2019 at 13:32
  • @KrzysztofKrzeszewski what does this mean most of the time, either it is or it is not or are we talking about different browser implementation Commented Sep 23, 2019 at 13:35
  • 1
    The ordering behavior is defined by the spec, but the order has nothing to do with the property names other than that "number" property names come before others. The fact remains that relying in any way on object property name ordering is an extremely fragile coding practice. Commented Sep 23, 2019 at 13:35
  • If you clear cache and run it again. it's gonna show the same order? Commented Sep 23, 2019 at 13:35

2 Answers 2

2

So you are trying to turn a Map (unordered) into an Array (ordered). Some browsers dump the keys based on the order they are added to the object. Some do it other ways. Since it is browser dependent the best you can aim for is sorting said list.

I would suggest that after you dump it to an array, you should .sort() it how you see fit. It accepts a function you would need. Granted, it is case specific, so you would need to likely leverage the optional passed in function for sort to compare it in the way which best works for your use case. Since sort's inputs can be as complex as you like, you could also use it to sort on the contents of said values instead of just the keys.

Sign up to request clarification or add additional context in comments.

Comments

0

As explained in this SO Answer,

[Objects are] an unordered collection of properties

Storing items by key in an object is very useful in order to retrieve them in one jump (when you know the key) but you lose the order. If you need to keep thinks in a specific order, always use arrays instead. So instead of having this object :

{
  "key1": {
    "name": "Jeff",
    "job": "Bartender"
  },
  "key2": {
    "name": "Jawad",
    "job": "Bus driver"
  }
}

You would have this array :

[
  {
    "any_unique_identifier_key": "key1",
    "name": "Jeff",
    "job": "Bartender"
  },
  {
    "any_unique_identifier_key": "key2",
    "name": "Jawad",
    "job": "Bus Driver"
  }
]

The downside is that when you are looking for a specific element in the array, you have to iterate through the whole thing (or use binary trees).

Comments