问题描述
某日开发小姐姐在维护一个老项目,突然测试反馈展示的顺序有问题了,一脸懵逼?,我一行代码没用动呢,咋回事,先看问题
服务端返回数据,期望展示顺序和服务端返回数据保持一致
const carTypes = [
{
"typeName":"新能源",
"typeNo":9
},
{
"typeName":"出租车",
"typeNo":1
},
{
"typeName":"中巴车",
"typeNo":6
},
{
"typeName":"自动驾驶",
"typeNo":16
},
]
复制代码
由于历史逻辑,代码中把数组对象改造成了 通过typeNo作为索引的对象格式
const carServiceMap = {}
Object.keys(carTypes).forEach((key) => {
carServiceMap[allBizs[key].typeNo] = allBizs[key].typeName;
});
console.log(carServiceMap) // 会输出什么?
复制代码
看到这里,请动动你的小脑袋,carServiceMap输出是怎样的?你的答案是不是这样的?
{
9:'新能源',
1:'出租车',
6:'中巴车',
16:'自动驾驶'
}
复制代码
如果是的话,那恭喜你答错啦!!正确答案应该是这样的
{
1:'出租车',
6:'中巴车',
9:'新能源',
16:'自动驾驶'
}
复制代码
发现了么,根据索引自动排序了,为什么对象内部会根据索引自动排序呢
问题原因
具体原因:262.ecma-international.org/6.0/#sec-or…
翻译:
9.1.12 [[OwnPropertyKeys]]()
调用 O 的 [[OwnPropertyKeys]] 内部方法时,采取以下步骤:
1.使 keys 变为一个空的 List
2.对于整数类型的 O 的每个自己的属性键 P,按照数字索引升序,放到属性列表中
a. 将 P 作为 keys 的最后一个元素。
3.对于 String 类型但不是整数索引的 O 的每个自己的属性键 P,按照属性的创建时间升序,放到属性列表中
a. 将 P 作为 keys 的最后一个元素。
4.对于 Symbol 类型的 O 的每个自己的属性键 P,按照属性的创建时间升序,放到属性列表中
a. 将 P 作为 keys 的最后一个元素。
5.返回 keys。
复制代码
解决方案:
-
直接使用数组
-
一定要转化为对象的时候,使用map
const carServiceMap = new Map() Object.keys(arr).forEach((key) => { carServiceMap.set(arr[key].typeNo,arr[key].typeName) }) for (var [key, value] of carServiceMap) { console.log(key, value); } 复制代码
参考:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END