Console 输出对象的奇特现象

作者: 错码匠 | 来源:发表于2016-11-24 15:24 被阅读46次

    对象内的属性列表是无序的!

    首先清楚一点,JS世界中(其他语言不了解)对象是一个包含各种“特性”的单一实体,它所包含的“特性”(属性/方法)是以键值对形式无序排列的,属性书写时的排列顺序不会影响对象属性的获取。比如下面这个对象:

        var object={c:3, b:2, a:1, d:4};
    

    开发者通过声明键名(object[a]===1object.b===2)可以调取对象任意的属性值。对象就是对象,一个包含各种特性(属性/方法)的单一对象。而排序是对诸多单一对象的群体做排序,而这个群体组成的是一个序列,序列的排序是有意义的,在设计需求中可以对一个序列做倒序、顺序的排列展示,而通常这种序列是以数组形式展现的:

        var array1=['a','b','c','d'];
    
        var array2=[
            {id:1, name:'Jack', age:32, gender:'male'},
            {id:2, name:'Mary', age:28, gender:'female'},
            {id:3, name:'Tom', age:18, gender:'male'},
            ...
        ];
    

    数组中每一个对象都对应着一个序号,通过序号可以取到对应的对象元素(array1[0]array2[2])。而回到对象个体上,对单一对象的属性来做排序显得毫无必要。

    Console 上的奇怪现象

    之所以要强调“对象内的属性列表是无序的”这个要点,是为了突出这个问题或者现象的怪异。我们用Chrome浏览器的调试工具做演示,来运行一段代码看看:

        console.log({3:3, 2:2, 1:1, 4:4});
    

    输出:{1: 1, 2: 2, 3: 3, 4: 4}!奇怪吗?结果按照数字键名的大小被重新排序输出了。那我们把键名换成字母是不是会按照字母顺序排序呢:

        console.log({c:3, b:2, a:1, d:4});
    

    输出:{c:3, b:2, a:1, d:4},并没有!

    chrome

    我终究还是清楚 Chrome 浏览器是优于IE之流的,于是试着打开Edge的调试窗口来看看:

    edge

    我们发现在Edge里以字母作为键名的对象属性集也被排序输出了!会不会是不同浏览器解析方式不同所至?要是这样的话node.js用了和Chrome相同的解析器v8,那么node.js的输出结果应该是一样的:

    node.js

    果然!再试试Firefox:

    firefox

    结果和Chrome一样。

    为什么?

    我也在找寻答案,也许是不同内核解析方式不同,也许只是调试工具带来的差异,这样做的原因是什么?
      如果是为方便开发人员调试,那edge做得更全面。

    这里有个相关问题的讨论帖:http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order

    相关文章

      网友评论

        本文标题:Console 输出对象的奇特现象

        本文链接:https://www.haomeiwen.com/subject/pkbbpttx.html