26

Do Object.keys() and Object.values() methods return arrays that preserve the same order?

I mean, suppose that we have the following object:

var obj = {};
obj.prop1 = "Foo";
obj.prop2 = "Bar";

If I call obj.keys() and obj.values() will they return properties with the same order?

prop1
prop2

Foo
Bar

or

prop2
prop1

Bar
Foo

Right?

So the following option is not possible, right?

prop1
prop2

Bar
Foo
FrozenHeart
  • 17,408
  • 26
  • 97
  • 212
  • It maintains index order – Emil S. Jørgensen Jan 20 '17 at 10:47
  • As long as the properties on the object are defined in that order and nothing changes those properties apart from their value, you'll get that order. Hence, it's advisable to define all the properies the object will have in advance and set the unknown values to null initially. Do note that alot of browser debuggers show the props of an object in alphabetical order, so if you inspect the element in the console, you might get a different order than the actual order the object was defined in. – Shilly Jan 20 '17 at 10:48
  • @Shilly *"are defined in that order"* - the definition order doesn't really matter for objects, properties must always be considered unordered for all practical purposes. – deceze Jan 20 '17 at 10:50
  • With no changes to the object between calling the two methods, they will always be in the same order as each other – Jaromanda X Jan 20 '17 at 10:50
  • @deceze Indeed, but the question is which order Object.keys() will return, and that order is fixed. – Shilly Jan 20 '17 at 10:50
  • 1
    `that order is fixed` yes and no, depends on what you mean ... try `var x = {b:1, a:2}; console.log(Object.keys(x)); delete x.b; x.b = 1; console.log(Object.keys(x));` ... however, at each console.log, Object.keys and Object.values will be in the same order as each other – Jaromanda X Jan 20 '17 at 10:53
  • That's exactly what I mean with 'the order is fixed as long as nothing changes those properties apart from their value'. By deleting the x.b property, you change the structure of the object and the new 'b' property will be defined as a new property after 'a'. If you would change your example to: `var x = {b:1, a:2}; console.log(Object.keys(x)); x.b = undefined; x.b = 1; console.log(Object.keys(x));` the order is still the same. – Shilly Jan 20 '17 at 11:03

1 Answers1

25

In short, Yes.

Both Object.keys and Object.values (and also Object.entries()) enumerate via for-in loop on the object.
Since both use the same [[Enumerate]], as long as they are called on an object with same unchanged own prototype (without deleting or adding keys between the keys and values calls), the order will be the same.

What will the order be?
It depends on how you initialized your object, which explorer you are using, and the order of which you have inserted additional keys to the object.
If the actual order is important to you as well (and not only that both keys and values result will be in to the same order) the bulletproof approach will be to use an array.

A different approach: Object.entries() will return a list of [key, value] pairs (in the same order provided by a for-in loop as well) which might be more helpful for your use case.

Maor Refaeli
  • 2,024
  • 2
  • 18
  • 31