background

In our daily development, many of the option values in the dropdown box are rendered as data via enumeration values (enums) returned from the back end. For example, a drop-down box looks like this:

If we want the order of the options in the drop-down box to be sorted by the data returned from the back end, there are two ways to do this. One is that the back end returns an array of data, and we iterate through that data in order. But if the back end returns an object like this,

Then we need to consider object.keys (), for… Whether a series of methods such as in traversing an object can be printed in the order in which the back-end properties are created.

Problem reproduction

Let’s take a look at the following code:

var obj = {
      name: 'abc',
      3: 'ccc',
      age: 23,
      class: 'first',
      hobby: 'basketball'
};
console.log(Object.keys(obj));
// ["3", "name", "age", "class", "hobby"]
Copy the code

As you can see, object.keys () does not guarantee the order of output attributes.

Keys does not guarantee the order of Object attributes?

This is described in mdN-object. keys

Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object. The ordering of the properties is the same as that given by looping over the properties of the object manually.

MDN-for… MDN-for… in

Array indexes are just enumerable properties with integer names and are otherwise identical to general object properties. There is no guarantee that for… in will return the indexes in any particular order… Because the order of iteration is implementation-dependent.

Different browsers implement this differently. But described in an articleProperty order is predictable in JavaScript objects since ES2015

According to the description of the article weight is Object getOwnPropertyNames, Reflect the ownKeys they are internal ownPropertyKeys this way, and he also gives objects in the article the rules of the properties of the output sequence

  1. When a number or string is used as a key, the output is sorted in ascending order
  2. Ordinary string keys are printed in the order they are defined
  3. Symbols also follows the same rules as strings
  4. If there are all three types of keys, the order is 1 -> 2 -> 3

Reflect.ownkeys () is not supported in IE

Object. GetOwnPropertyNames () better compatibility

But if you want to use Object.keys, whether this is based on the ownPropertyKeys method depends on the browser implementation.

The standard reference

As described in ecMA-262 (ECMAScript 3), the order in which attributes are traversed for a for-in statement is determined by the order in which attributes are written when the object is defined.

In the ecMA-262 (ECMAScript) fifth edition, the traversal mechanism of for-in statements has been adjusted, and the order of traversal of attributes is not specified.

Chrome Opera’s JavaScript parsing engine follows the new ECMA-262 version 5 specification after reproducing the code above and reviewing information available on the web. Therefore, the traversal order is not the property build order when iterating through object properties using a for-in statement. IE6 IE7 IE8 Firefox Safari’s JavaScript parsing engine follows the older ECMA-262 version 3 specification, and the order in which attributes are traversed is determined by the order in which they are built.

Chrome Object. Keys output sequence and cause analysis

Chrome’s JS engine follows a rule when iterating through object properties:

They extract all of the attributes whose parseFloat of the key is a non-negative integer, sort the attributes in numerical order first, and then iterate through the remaining attributes in the order defined by the object. For example, the following output:

Let obj = {' b ':' testb ', 'a' : 'testa', '1', 'test1', 'test' : 'test', '2', 'test2'} the console. The log (Object. Keys (obj)); // [1, 2, 'b', 'a', 'test ']Copy the code

Chrome works this way because V8 maintains two attributes for object access, placing numbers in the linear Elements attribute and storing them in order. Non-numeric attributes are put into properties, not sorted. Look for attributes elements and then properties. The V8 engine does this for reasons that can be found in Li Bing’s teacherWhat strategies does V8 use to speed up access to object properties?Found.

conclusion

Our current project is you just need to compatible with Chrome, it can be seen as long as it is the return value of the array, the attribute value of the key is not digital mixed with string, then can use Object. The order of the keys and can be read by a guarantee, guarantee the drop-down options apply colours to a drawing order, without the backend for this return to array, The back end also saves the effort and risk of changing all the previous data and code.

reference

Why is the order of internal properties traversal in JS out of order object.keys (..) The order of object attributes? Property order is predictable in JavaScript objects since ES2015 jS In traverses object attributes in order