Object.keys()
The ordering of properties when traversing an object is not guaranteed. Starting from this sentence, we set out to Object.keys
go further and further on the "wrong path".
Object.keys
The order of object properties is not guaranteed?
I checked MDN-Object.keys with the attitude of doubting this sentence:
Object.keys()
returns an array whose elements are strings corresponding to the enumerable properties found directly uponobject
. The ordering of the properties is the same as that given by looping over the properties of the object manually.
There is no direct explanation, just that it is the same as manual traversal, then check 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.
Because the order of iteration is dependent on browser implementation, the conclusion is not guaranteed.
Guarantee order of object properties
If Object.keys()
the order of object properties cannot be guaranteed, is there any other method in JavaScript that can guarantee the order of object properties.
ownPropertyKeys
: Specifies the object attribute traversal order
Found a concise style article: Property order is predictable in JavaScript objects since ES2015 , which mentions ownPropertyKeys
methods inside JavaScript that define the order of object property traversal:
- integer-like keys in ascending order
- normal keys in insertion order
- Symbols in insertion order
- if mixed, order: interger-like, normal keys, Symbols
Interget-like keys, in addition to 0
numbers 1
, also include "2"
key types that are returned in ascending order; normal keys are string
types, which Symbol
are returned in the order of insertion. If multiple types are included, follow the order of interger-like keys, normal keys, and Symbols from front to back. (The order of console output seems to be the same...)
Object.getOwnPropertyNames()
ownPropertyKeys
Methods implemented based on internal methods include Object.getOwnPropertyNames
and Reflect.ownKeys
, these two methods guarantee the order of object attributes.
Reflect.ownKeys()
The returned result is equivalent to Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
an array consisting of enumerable, non-enumerable, and Symbols properties that are directly hung on the target object. But this method is not chosen here, mainly considering compatibility (proposed by ES6, not supported by IE):
Object.getOwnPropertyNames()
Returns a combination of enumerable and non-enumerable properties that are directly attached to the target object. It was proposed in ES5, has better compatibility, and supports IE9+:
Manually Object.keys()
add order
It suddenly occurred to me that although Object.keys()
the array of object attributes returned by itself cannot guarantee the order, the returned results can be sorted manually. In addition, the attribute names encountered in the project are all normal key, which is a string type, and only need to be replaced with Object.keys(value).sort()
.
However lodash...
However, after asking a colleague, I was told that lodash has a isequal
method:
Performs a deep comparison between two values to determine if they are equivalent.
Note: This method supports comparing arrays, array buffers, booleans, date objects, error objects, maps, numbers,
Object
objects, regexes, sets, strings, symbols, and typed arrays.Object
objects are compared by their own, not inherited, enumerable properties. Functions and DOM nodes are compared by strict equality, i.e.===
.
Hmm...fits the scene here.
Then curiosity drove me to take a look at isequal
the source code of lodash. During the in-depth comparison object
, the value values corresponding to the same key are compared, so there is no stringification process, and there is no issue about the order of object attributes... ( Implementing this manually is a bit convoluted, but it can be used directly and is safe)
Hmm...well, I finally compromised and used the lodash isequal
method.
summary
The traversal of object attributes is a fuzzy area when it comes to looping, Object.keys()
and forin
the order of object attributes is not guaranteed; Object.getOwnPropertyNames
based on the built-in method ownPropertyKeys
, there is a guaranteed order of object attributes, and the compatibility is very good, and it supports IE9+;