Elements order in a “for (… in …)” loop

后端 未结 9 684
终归单人心
终归单人心 2020-11-21 07:27

Does the \"for…in\" loop in Javascript loop through the hashtables/elements in the order they are declared? Is there a browser which doesn\'t do it in order?
The object

相关标签:
9条回答
  • 2020-11-21 08:01

    This does not answer the question per se, but offers a solution to the basic problem.

    Assuming that you cannot rely on order to preserved, why not use an array of objects with key and value as properties?

    var myArray = [
        {
            'key'   : 'key1'
            'value' : 0
        },
        {
            'key'   : 'key2',
            'value' : 1
        } // ...
    ];
    

    Now, it is up to you to ensure that the keys are unique (assuming that this is also important to you. As well, direct addressing changes, and for (...in...) now returns indexes as 'keys'.

    > console.log(myArray[0].key);
    key1
    
    > for (let index in myArray) {console.log(myArray[index].value);}
    0
    1
    
    See the Pen for (...in...) addressing in order by JDQ (@JDQ) on CodePen.

    0 讨论(0)
  • 2020-11-21 08:10

    As stated by other answers, no, the order is not guaranteed.

    If you want to iterate in order, you can do something like:

    let keys = Object.keys(myObject);
    for (let key of keys.sort()) {
      let value = myObject[key];
      
      // Do what you want with key and value 
    }
    

    Note that performance-wise, this is not optimal, but that's the price when you want a nice alphabetical display.

    0 讨论(0)
  • 2020-11-21 08:11

    The order cannot be trusted. Both Opera and Chrome return the list of properties unordered.

    <script type="text/javascript">
    var username = {"14719":"A","648":"B","15185":"C"};
    
    for (var i in username) {
      window.alert(i + ' => ' + username[i]);
    }
    </script>
    

    The code above shows B, A, C in Opera and C, A, B in Chrome.

    0 讨论(0)
  • 2020-11-21 08:12

    Bumping this a year later...

    It is 2012 and the major browsers still differ:

    function lineate(obj){
        var arr = [], i;
        for (i in obj) arr.push([i,obj[i]].join(':'));
        console.log(arr);
    }
    var obj = { a:1, b:2, c:3, "123":'xyz' };
    /* log1 */  lineate(obj);
    obj.a = 4;
    /* log2 */  lineate(obj);
    delete obj.a;
    obj.a = 4;
    /* log3 */  lineate(obj);
    

    gist or test in current browser

    Safari 5, Firefox 14

    ["a:1", "b:2", "c:3", "123:xyz"]
    ["a:4", "b:2", "c:3", "123:xyz"]
    ["b:2", "c:3", "123:xyz", "a:4"]
    

    Chrome 21, Opera 12, Node 0.6, Firefox 27

    ["123:xyz", "a:1", "b:2", "c:3"]
    ["123:xyz", "a:4", "b:2", "c:3"]
    ["123:xyz", "b:2", "c:3", "a:4"]
    

    IE9

    [123:xyz,a:1,b:2,c:3] 
    [123:xyz,a:4,b:2,c:3] 
    [123:xyz,a:4,b:2,c:3] 
    
    0 讨论(0)
  • 2020-11-21 08:16

    in IE6, the order is not guaranteed.

    0 讨论(0)
  • 2020-11-21 08:17

    From the ECMAScript Language Specification, section 12.6.4 (on the for .. in loop):

    The mechanics of enumerating the properties is implementation dependent. The order of enumeration is defined by the object.

    And section 4.3.3 (definition of "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.

    I guess that means you cant rely on the properties being enumerated in a consistent order across JavaScript implementations. (It would be bad style anyway to rely on implementation-specific details of a language.)

    If you want your order defined, you will need to implement something that defines it, like an array of keys that you sort before accessing the object with it.

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