1

I was under impression that ES6 has introduced new features to get object properties in creation order using methods like Object.getOwnPropertyNames(), Reflect.ownKeys etc but while working on a problem I realised for negative keys the order is not maintained.

const object1 = {
  "-1": 'somestring',
  "3": 42,
  "2": false,
  "-3": true
};

console.log(Object.getOwnPropertyNames(object1));
// expected output: Array ["-1", "3, "2", "-3"]
// actual output: ["2", "3", "-1", "-3"]

console.log(Object.keys(object1));

What would be the correct way to get keys in creation order for such scenario?

EDIT: I dont want to sorted order, looking for creation order

Anupam
  • 7,966
  • 3
  • 41
  • 63
  • positive 32 bit integers are sorted by value and appears first. – Nina Scholz Jul 09 '19 at 18:00
  • only natural numbers are sorted in order – WilliamNHarvey Jul 09 '19 at 18:01
  • *"I dont want to sorted order, looking for creation order"* - mentioned this on an answer below but i'll re-iterate it here: **Because you have positive integer keys, it's not possible.** It's why objects should never be used for anything that's order-sensitive. Consider a `Map` instead. – Tyler Roper Jul 09 '19 at 18:08
  • From MDN page about [`getOwnPropertyNames`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames): _"The ordering of the non-enumerable properties in the array and the ordering among the enumerable properties is not defined."_ – JLRishe Jul 09 '19 at 18:11

2 Answers2

2

Yes, the ordering of keys does distinguish between array indices (basically non-negative integers) and others. To get your keys as sorted integers, use

Object.keys(object1).map(Number).sort((a, b) => a-b)
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    true, but what if we want the creation order not sorted order? e.g keys [-1, 0, 3, 2, -3] – Anupam Jul 09 '19 at 18:02
  • 2
    @anu You cannot. It's precisely why objects shouldn't be used for anything sensitive to order. – Tyler Roper Jul 09 '19 at 18:06
  • 1
    @anu Objects maintain creation order only for non-array-index keys, those always come first. Objects are still the wrong data structure when you want something ordered - store the order explicitly instead. Or use a `Map` at least. – Bergi Jul 09 '19 at 18:06
  • Hmm that makes sense – Anupam Jul 09 '19 at 18:09
  • Property keys are traversed in the following order: First, the keys that are integer indices in ascending numeric order. Then, all other string keys, in the order in which they were added to the object. Lastly, all symbol keys, in the order in which they were added to the object. – Monika Mangal Jul 09 '19 at 18:09
  • For more details about the traversing order you can read - https://2ality.com/2015/10/property-traversal-order-es6.html – Monika Mangal Jul 09 '19 at 18:10
  • @MonikaMangal Thanks for the clarification – Anupam Jul 09 '19 at 18:13
0

This is will, in case you don't want to change the type of the keys and keep them as strings.

Object.getOwnPropertyNames(object1).sort()
Monika Mangal
  • 1,665
  • 7
  • 17