Chrome如果键是数字,重新排序对象键,这正常/符合预期吗?
Chrome如果键是数字,重新排序对象键,这正常/符合预期吗?
我注意到一个在电子商务网站上评估一些鞋码并在屏幕上输出它们的代码在Chrome中打乱了顺序。
给定的JSON可以是:
{
"7": ["9149", "9139", "10455", "17208"],
"7.5": ["9140", "9150", "10456", "17209"],
"8": ["2684", "9141", "10457", "17210"],
"8.5": ["9142", "10444", "10458", "17211"],
"9": ["2685", "9143", "10459", "17212"],
"9.5": ["10443", "9144", "10460", "17213"]
}
......其中尺码以半码递增。
将其转换为对象并通过键进行迭代后,自然顺序会被尊重,输出结果为:
7, 7.5, 8, 8.5等。
但是在Chrome中,'看起来'像是整数的键总是首先从对象中出现,所以for... in循环的输出结果是:
7, 8, 9, 7.5, 8.5, 9.5 ...
Object.keys(sizes); // ["7", "8", "9", "7.5", "8.5", "9.5"]
这是测试用例:https://jsfiddle.net/wcapc46L/1/
只有整数受到影响,看起来像是Webkit / Blink有一个优化,更喜欢数字属性,可能与分支预测有关。
如果在对象键前加上任何字符,顺序保持不变,按照预期的先进先出工作。
我记得读到过对象属性的顺序没有保证,但同时,这非常令人恼火,并且会导致在仅针对Chrome用户修复这个问题时需要付出相当大的努力。
有任何想法吗?这可能是一个会被修复的错误吗?
编辑此外,我现在在v8的错误跟踪器上发现了这个问题:
https://code.google.com/p/v8/issues/detail?id=164
看起来Blink不想修复这个问题,并将继续是唯一一个会这样做的浏览器。
更新 Webkit / Blink所拥有的哈希表优化现在已经进入了Gecko(FF 27.0.1)- https://jsfiddle.net/9Htmq/ 的结果为
7,8,9,7.5,8.5,9.5
。在键前加上_
可以返回正确/预期的顺序。更新 2017 人们仍在对此进行投票和编辑,所以 - 看起来它似乎并不影响
Map
/WeakMap
,Set
等(正如主要示例更新所示)