Does JavaScript Guarantee Object Property Order

Does JavaScript guarantee object property order?

The iteration order for objects follows a certain set of rules since ES2015, but it does not (always) follow the insertion order. Simply put, the iteration order is a combination of the insertion order for strings keys, and ascending order for number-like keys:

// key order: 1, foo, bar
const obj = { "foo": "foo", "1": "1", "bar": "bar" }

Using an array or a Map object can be a better way to achieve this. Map shares some similarities with Object and guarantees the keys to be iterated in order of insertion, without exception:

The keys in Map are ordered while keys added to object are not. Thus, when iterating over it, a Map object returns keys in order of insertion. (Note that in the ECMAScript 2015 spec objects do preserve creation order for string and Symbol keys, so traversal of an object with ie only string keys would yield keys in order of insertion)

As a note, properties order in objects weren’t guaranteed at all before ES2015. Definition of an Object from ECMAScript Third Edition (pdf):

4.3.3 Object

An object is a member of the
type Object. It is an unordered collection of properties each of which
contains a primitive value, object, or
function. A function stored in a
property of an object is called a
method.

Does JavaScript guarantee object property order during declaration?

Even though this is clearly a duplicate of Does JavaScript Guarantee Object Property Order?, I'll go ahead and answer anyway.

There is zero guarantee of order in your "unordered collection of properties". However with modern implementations of Javascript, you can expect that the properties will usually be in order as you defined them.

As long as the expected order is preferable, but not critical, it is reasonable in most cases to just assume they will be in order. But if your business logic depends on that order to be guaranteed, then you definitely need to rethink your strategy.

Okay. I see now what you are actually asking. In this particular context, the answer is "yes and no".

Your functions are being called statically as your object is being defined. So the function defining property a will always be called before the function defining property b.

However, console.log is an asynchronous function, and you cannot rely on it to log value A before it logs value B

Sorting object property by values

Move them to an array, sort that array, and then use that array for your purposes. Here's a solution:

let maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};
let sortable = [];
for (var vehicle in maxSpeed) {
sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
return a[1] - b[1];
});

// [["bike", 60], ["motorbike", 200], ["car", 300],
// ["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

Once you have the array, you could rebuild the object from the array in the order you like, thus achieving exactly what you set out to do. That would work in all the browsers I know of, but it would be dependent on an implementation quirk, and could break at any time. You should never make assumptions about the order of elements in a JavaScript object.

let objSorted = {}
sortable.forEach(function(item){
objSorted[item[0]]=item[1]
})

In ES8, you can use Object.entries() to convert the object into an array:

const maxSpeed = {
car: 300,
bike: 60,
motorbike: 200,
airplane: 1000,
helicopter: 400,
rocket: 8 * 60 * 60
};

const sortable = Object.entries(maxSpeed)
.sort(([,a],[,b]) => a-b)
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});

console.log(sortable);

Javascript - maintain key order when going from object -> array

No. As you wrote:

I know key order isn't guaranteed in JS objects

If you want the order you need to use an array. If you have an object, then there is no defined order to the properties.

Object keys in different order after running Object.keys

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.

Object property ordering in javascript

Although Chrome may guarantee property order when using numbers as indexes in objects, the ECMA specification does not say it should do that, so by guarantee I'd not rely on this behavior. I suggest you to restructure your data to use arrays when you want to keep data order.



Related Topics



Leave a reply



Submit