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

Dim*_*off 25 javascript json google-chrome javascript-objects

我注意到某些代码评估了某个电子商务网站的鞋码并将其输出到屏幕上,这使得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"]
}
Run Code Online (Sandbox Code Playgroud)

...将尺寸增加一半.

转换为对象并迭代键后,自然顺序得到尊重,它们出现为:

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"]
Run Code Online (Sandbox Code Playgroud)

以下是测试用例:https://jsfiddle.net/wcapc46L/1/

它只影响整数,似乎Webkit/Blink有一个优化,它更喜欢数字的对象属性,也许它与分支预测或其他什么有关.

如果在对象键前面加上任何字符,则顺序不受影响并按预期工作 - FIFO

我想我会记得读到对象的属性顺序没有任何保证,但与此同时,这是极端烦人的,并且会导致为Chrome用户单独修复它的相当大的努力.

有任何想法吗?这可能是一个会被修复的错误吗?

另外编辑,我现在发现这是v8 bug跟踪器上的一个问题:

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/ WeakMap,Set等(通过已更新的主要例子作为证明)

Mic*_*rks 21

这是v8处理关联数组的方式.已知问题问题164但遵循规范,因此标记为"按预期工作".循环关联数组没有必需的顺序.

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

该标准将在下一个ECMAScript规范中发生变化,迫使[chrome]开发人员改变这一点.

  • 好吧,傻傻的Resig先生,如果他依靠这个.依赖于非均匀观察而非指定的行为是不良,不可靠代码的处方. (4认同)
  • 保留订单,因为所有其他浏览器已经这样做了. (2认同)