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

问题重现

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

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 在前面了,用户肯定希望先看到新的车型的,这不科学!

解释

查阅了一些文档后,得出了以下有效结论:

  1. 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.
  2. Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。

而 Chrome Opera 中使用 for-in 语句遍历对象属性时会遵循一个规律:

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

猜想

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

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

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

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

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

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

解决问题

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

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

猜你喜欢

转载自www.cnblogs.com/everlose/p/12501222.html
今日推荐