为什么 JS 对象内部属性遍历的顺序乱了

栏目: IT技术 · 发布时间: 5年前

内容简介:需求是要获取一个车型列表,并且输出到页面上按年份排序,故而接口提供的对象简化如下??? 为什么 2013 在前面了,用户肯定希望先看到新的车型的,这不科学!查阅了

问题重现

需求是要获取一个车型列表,并且输出到页面上按年份排序,故而接口提供的对象简化如下

let obj = {  
    '2018': {
        modelCode: "204313",
        modelName: "2018款 Vanquish 6.0L S Coupe"
    },
    '2017': {
        modelCode: "202479",
        modelName: "2017款 Rapide 6.0L AMR"
    },
    '2013': {
        modelCode: "139705",
        modelName: "2013款  Rapide  6.0L S"
    }
}

console.log(obj)  
// {2013: {…}, 2017: {…}, 2018: {…}}

??? 为什么 2013 在前面了,用户肯定希望先看到新的车型的,这不科学!

解释

查阅了 ECMA-262 3rd edition ,如下文 It is an unordered collection of properties 就说到 ES3 标准的对象不排序,插入是啥顺序,遍历就是啥顺序

An object is a member of the type 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.

而我查阅了 ECMA-262 5.1 edition ,如下文,读者们应该留意到了少了 unordered collection 的描述。并且之后的 ES 版本对对象的描述都是如此。

an object is a member of the remaining built-in type Object; and a function is a callable object. A function that is associated with an object via a property is a method.

故此,我能得出结论 Chrome 等新版浏览器 JS 引擎遵循的是新版 ECMA-262 5th。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。而 IE6、7、8 等旧版本浏览器的 JS 解析引擎遵循的是较老的 ECMA-262 3rd,属性遍历顺序由属性构建的顺序决定。

故此 Chrome 的 JS 引擎遍历对象属性时会遵循一个规律:

它们会先提取所有 key 的 parseFloat 值为非负整数的属性,然后根据数字顺序对属性 排序 首先遍历出来,然后按照对象定义的顺序遍历余下的所有属性。

猜想

按照上面的解释,那么我来一个例子

let obj = {  
    'b': 'testb',
    'a': 'testa',
    '1': 'test1',
    '测': 'test测',
    '2': 'test2'
}

console.log(Object.keys(obj));

// [1, 2, 'b', 'a', '测']

果然会把 '1' 和 '2' 这种能被 parseFloat 转化为正整数的提到前面并且按照升序排

而 'a' 和 '测' 没法转为整数那就排在 '1'、'2' 后并按照构建时的顺序拍

解决问题

回到问题,对象既然不能保证其顺序,那么使用数组来进行遍历吧。

当然业务中如果需要查某个年份的车型,而不想要每次都遍历一遍的来找的话。可以维护两份数据。一份数组,用于遍历输出,一份对象,用于查。

补充

直到最近在极客时间翻阅到李兵老师的 图解 Google V8 的第三节 "V8采用了哪些策略提升了对象属性的访问速度?" 时,我终于发现了更深层次的解释。

借下图说法:V8 里的对象其实维护两个属性,会把数字放入线性的 elements 属性中,并按照顺序存放。会把非数字的属性放入 properties 中,不会排序,顺便说一句它可能是线性结构,取决于属性数量的多少。寻找属性时先 elements 而后在 properties。

为什么 JS 对象内部属性遍历的顺序乱了


以上所述就是小编给大家介绍的《为什么 JS 对象内部属性遍历的顺序乱了》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learn Python the Hard Way

Learn Python the Hard Way

Zed Shaw / Example Product Manufacturer / 2011

This is a very beginner book for people who want to learn to code. If you can already code then the book will probably drive you insane. It's intended for people who have no coding chops to build up t......一起来看看 《Learn Python the Hard Way》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具