Iteration order for in.in - not by inserting (no more?)

According to my research, the order of the keys in the for..in loop must be undefined / unreliable - but if you cannot leave it, it must be in the insertion order, but this is not:

I am retrieving this data object from a database, sorted by name:

 var travel = { '2': { name: 'bus', price: 10 }, '3': { name: 'foot', price: 0 }, '1': { name: 'taxi', price: 100 } } for (way in travel) console.log( travel[way].name ) // => taxi, bus, foot 

Keys get an ordered number (in all Chrome, Firefox, and Edge). Why?

And (since I was wrong), how can I iterate over them in order .name ?

+6
source share
2 answers

According to my research, the order of the keys in the for..in loop should be undefined / unreliable

Undefined, yes.

  • but if left undisturbed, it should be in the input order

No, you were right the first time: It is undefined. Even in ES2015 (hereinafter referred to as β€œES6”) and higher, which provide a property order for some other operations, the older for-in and Object.keys do not need to follow the order defined for the new ones.

In these other operations ( Object.getOwnPropertyNames , JSON.serialize , ...), the order ( indicated here ) is not purely the insertion order: properties whose names are array indexes according to the specification specification *, first, in numerical order. Most of the core JavaScript engines have updated the for-in processing according to their handling of these new operations (many have already processed the indexes of arrays in different ways, but they varied depending on whether they were placed before the indices without an array or after), but again, it is undefined and you should not rely on it.

If you need a clean insertion order, ES2015 Map provides that regardless of key value. There are no objects.

Here's an example using Map :

 const map = new Map([ ['2', { name: 'bus', price: 10 }], ['3', { name: 'foot', price: 0 }], ['1', { name: 'taxi', price: 100 }] ]); for (const entry of map.values()) { // bus, foot, taxi console.log(entry.name); } 

* Specification specification for array index:

An integer index is the key of the String-value property, which is a canonical numeric string (see 7.1.16) and whose numeric value is +0 or a positive integer ≀ 2 53-1 . The array index is an integer index whose numerical value I is in the range +0 ≀ i <2 32-1 .

+3
source

In practice, a javascript object iterates over the keys in insertion order, unless the keys are numeric. This is probably due to the need to do an iteration of the array (arrays are also objects), ordered by key.

So, your choice - follow the standard and use ES6 Map or arrays of objects to guarantee the iteration order - make your keys always non-numeric and hope for the best

+1
source

Source: https://habr.com/ru/post/1015470/


All Articles