Can I assume the order of response from Object.keys same?

后端 未结 2 1286
南方客
南方客 2021-01-25 12:23
{\"/book\":1,\"/order\":2,\"deliver\":3}

In the UI of my app, When I click on /book, I know from the map, what step to go to. At times I just want to

相关标签:
2条回答
  • 2021-01-25 12:28

    The ECMAScript 5.1 specification states that

    When the keys function is called with argument O, the following steps are taken:

    1. If the Type(O) is not Object, throw a TypeError exception.
    2. Let n be the number of own enumerable properties of O
    3. Let array be the result of creating a new Object as if by the expression new Array(n) where Array is the standard built-in constructor with that name.
    4. Let index be 0.
    5. For each own enumerable property of O whose name String is P: (a) Call the [[DefineOwnProperty]] internal method of array with arguments ToString(index), the PropertyDescriptor {[[Value]]: P, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. (b) Increment index by 1.
    6. Return array.

    If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used in step 5 of this algorithm.

    The Mozilla Development Network has this to say about the for-in loop:

    A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting).

    And the reference to the delete operator leads to this:

    Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses delete on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property value is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its old position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.

    So if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.

    I think the conclusion to draw from this is that, within a single browser, the order will be arbitrary but consistent but if you compare multiple browsers then the order may differ across those browsers (especially if you are deleting and re-adding properties).

    Edit:

    If you want to sort the keys based on the associated value then you can do something like this:

    var map = { b: 2, a: 1, c: 3 };
    
    var keys = Object.keys( map );
    
    console.log( keys ); // [ 'b', 'a', 'c' ]
    
    var sorted_keys = keys.slice(0); // sliced so that we can see the difference in order
    
    sorted_keys.sort( function( a, b ){ return map[a] - map[b]; } );
    
    console.log( sorted_keys ); // [ 'a', 'b', 'c' ]
    
    0 讨论(0)
  • 2021-01-25 12:45

    It is up to the implementation. From the ES5 spec on Object.keys:

    If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used in step 5 of this algorithm.

    The "step 5" mentioned there does not specify an order:

     5. For each own enumerable property of O whose name String is P...

    0 讨论(0)
提交回复
热议问题