2

In JavaScript Reflect.ownKeys() is the only function that returns both regular keys and keys that are symbols, as far as I know of at least. Other functions--for example Object.getOwnPropertyNames()--always return the keys in the order of declaration. However, with Reflect.ownKeys() the symbols are always at the end, regardless of that order.

Consider the following example:

const symbolProperty = Symbol('symbolProperty');

const object = {

    [symbolProperty]: 'Symbol Property',
    regularProperty: 'Regular Property'

};

console.log(Reflect.ownKeys(object));

// Returns 0: "regularProperty", 1: Symbol("symbolProperty")

Is there any way I can get all keys in the predictable order of declaration, like with Object.getOwnPropertyNames()? So for my example:

// 0: Symbol("symbolProperty"), 1: "regularProperty"

Please note that this should work with any object, without a separate array keeping track of the keys, or a similar "hack." If anyone knows how I can modify the array or of a different function to achieve the expected result it would be greatly appreciated.

Edit: The behavior of Object.getOwnPropertyNames() is implementation dependent, so depending on the environment it may not produce the results I observed and mentioned in this question.

Ood
  • 1,445
  • 4
  • 23
  • 43
  • 1
    This is what ES2015 specifies: positive integer keys in numeric order, string keys in insertion order, then symbol keys in insertion order. See https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order/38218582#38218582 – Barmar Jul 01 '23 at 17:56
  • Use a `Map` if you want everything in insertion order. – Barmar Jul 01 '23 at 17:57
  • @Barmar What would I use to get the insertion order though? – Ood Jul 01 '23 at 17:58
  • Insertion order is the same as declaration order when it's created with an object literal. – Barmar Jul 01 '23 at 17:59
  • @Dai It always returned the correct order for me when logging regular objects to the console. If it is inaccurate I can update my question to clarify that. – Ood Jul 01 '23 at 18:00
  • 1
    This [older question](https://stackoverflow.com/questions/30076219/does-es6-introduce-a-well-defined-order-of-enumeration-for-object-properties) and its accepted answer has a lot more detail.\ – Pointy Jul 01 '23 at 18:02
  • 1
    That's implementation-dependent, not part of the language requirement. – Barmar Jul 01 '23 at 18:02

1 Answers1

1

You can iterate over the map and get keys in the order they were inserted

const symbolProperty = Symbol('symbolProperty');

const map = new Map([
    [symbolProperty, 'Symbol Property'],
    ['regularProperty', 'Regular Property']
]);

for (const key of map.keys()) {
    console.log(key.toString()); //toString() only to show Symbol in console
}
dippas
  • 58,591
  • 15
  • 114
  • 126
  • Perfect, this should work for my use case. Thank you so much, will accept when I can! – Ood Jul 01 '23 at 18:03