一尘不染

如果数字是正常值/预期值,Chrome会重新排序对象键

json

我注意到某些评估电子商务网站某些鞋子尺码并将其输出到屏幕上的代码弄乱了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进行了优化,使其 更喜欢 数字对象属性,这可能与Branch Prediction或其他有关。

如果为对象键添加任何字符作为前缀,则该顺序不会受到影响并按预期工作-FIFO

我想我记得读过,没有保证对象属性的顺序,但是同时,这非常烦人,并且会导致为单独使用chrome的用户进行大量的修复工作。

有任何想法吗?这有可能会得到修复的错误吗?

进行 额外的 编辑 ,现在我发现这是v8错误跟踪器上的一个问题:

http://code.google.com/p/v8/issues/detail?id=164

看起来Blink不想解决此问题,它将仍然是唯一可以解决此问题的浏览器。

更新 webkit / blink拥有的哈希表优化功能,现在已进入壁虎(FF 27.0.1)-http:
//jsfiddle.net/9Htmq/中的结果7,8,9,7.5,8.5,9.5_在键返回正确/预期顺序之前应用。

2017年更新 人们仍然upvoting和编辑会这样-这似乎并不影响Map/ WeakMapSet等等(这表现在已更新的主要例子)


阅读 177

收藏
2020-07-27

共1个答案

一尘不染

这是v8处理关联数组的方式。已知问题Issue
164,
但遵循规范,因此标记为“按预期工作”。没有遍历关联数组的顺序。

一个简单的解决方法是在数字值前加上字母,例如:'size_7':['9149','9139']etc。

该标准将在下一个ECMAScript规范中更改,强制[chrome]开发人员进行更改。

2020-07-27