Javascript Chrome重新排序对象键(如果是数字),这正常/预期吗

Javascript Chrome重新排序对象键(如果是数字),这正常/预期吗,javascript,json,google-chrome,javascript-objects,Javascript,Json,Google Chrome,Javascript Objects,我注意到,某些代码评估了电子商务网站的一些鞋码,并将其输出到屏幕上,这扰乱了Chrome中的订单 给定的JSON可以是: { "7": ["9149", "9139", "10455", "17208"], "7.5": ["9140", "9150", "10456", "17209"],

我注意到,某些代码评估了电子商务网站的一些鞋码,并将其输出到屏幕上,这扰乱了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的输出。。。在循环中是:

7,8,9,7.5,8.5,9.5

以下是测试用例:

它只影响整数,似乎Webkit/Blink有一个优化,更喜欢数值对象属性,可能与分支预测或其他有关

如果使用任何字符作为对象关键帧的前缀,则顺序将不受影响,并按预期工作-FIFO

我想我记得我读过一篇文章,文章中没有关于对象属性顺序的保证,但同时,这非常烦人,而且仅仅为chrome用户修复它会花费大量的精力

有什么想法吗?这可能是一个会被修复的bug吗

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

看起来Blink不想解决这个问题,并且仍然是唯一可以解决这个问题的浏览器

更新无论webkit/blink拥有什么样的哈希表优化功能,现在已经进入gecko(FF 27.0.1)-结果是
7,8,9,7.5,8.5,9.5
。在按键返回正确/预期顺序之前应用

2017年更新人们仍在对此进行更新和编辑,因此-它似乎不会影响
地图
/
WeakMap
等(如更新的主要示例所示)


当用作索引/属性名时,Chrome似乎将整数字符串视为数字类型

我认为依靠Javascript实现来保持在某些情况下是对象属性的顺序,在其他情况下(当然是chrome)数组索引,显然是一种不安全的方法,规范中可能没有定义枚举顺序。我建议在JSON中添加一个表示排序顺序的附加属性:

{
    "7":{"sortOrder":1,"data":["9149","9139","10455","17208"]},
    "7.5":{"sortOrder":2,"data":["9140","9150","10456","17209"]}
    //etc
}

我想你不能把这叫做虫子。就像你自己说的,对于对象的属性如何排序没有保证。

它们被视为字符串,因为它们是字符串。我最好的建议是在你所有的钥匙上使用相同的“精度”

{
  "7.0": ["9149", "9139", "10455", "17208"],
  "7.5": ["9140", "9150", "10456", "17209"],
  "8.0": ["2684", "9141", "10457", "17210"],
  "8.5": ["9142", "10444", "10458", "17211"],
  "9.0": ["2685", "9143", "10459", "17212"],
  "9.5": ["10443", "9144", "10460", "17213"]
}
所以用“8.0”代替“8”,等等

即便如此,也没有保证,但更有可能的是,它们将以相同的顺序出现


为了更好地保证,请根据键执行排序,将值按排序顺序放入数组。

当迭代对象的属性时,ECMAScript规范中指定的顺序是未定义的,不应依赖您在某些环境中观察到的任何顺序。如果需要订购,请使用
数组

这是v8处理关联数组的方式。已知问题,但符合规范,因此标记为“按预期工作”。在关联数组中循环没有必需的顺序

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


该标准将在下一个ECMAScript规范中更改,迫使[chrome]开发人员更改此标准。

我发现了一个使用下划线.js的简单方法

myArray = _.sortBy(myArray, function(num){ return Math.ceil(num); });

耶!myArray在所有浏览器中都恢复了正确的顺序。

我的键太重要了,我无法将它们转换为字符串。相反,我创建了另一个数组,它只维护键的顺序

<?php 
$origArray = valueReturnedFromFunction();
$preservedOrder = array_keys($origArray);
?>
<script>
var origArray = <?php echo json_encode($origArray)?>;
var preservedOrder = <?php echo json_encode($preservedOrder )?>;

for(i in preservedOrder){
    var item = origArray[i];
    ...
}
</script>

var origArray=;
var-Dorder=;
(我在保护者公园){
var项目=原加雷[i];
...
}

更改是支持chrome的当前实现,还是支持保留定义顺序?保留顺序,因为所有其他浏览器都已经这样做了。“标准将在下一个ECMAScript规范中更改,迫使开发人员更改。”真的吗?证据在哪里?最近的ECMAScript 5规范没有指定顺序。听起来像是在最后一分钟掉下来的;谁敢说下次不会再发生这种事了?这可能不是规范的一部分。我在约翰·雷斯格的博客上读到过。好吧,愚蠢的雷西格先生,如果他相信这一点的话。依赖于非一致观察而不是指定的行为会导致糟糕的、不可靠的代码。遗憾的是,即使这对测试用例有效,这也不是实现的选项。尺码有多种选择,如“S、M、L、XL、XXL”或“44、44.5、44.5”或“一种尺码”等,由商户根据每种产品定义。对MYSQL的输出进行排序涉及到巨大的逻辑,因此它以正确的顺序到达,而不是以字符串的形式到达-它涵盖了大约40个不同的大小,这些大小是按照优先顺序预定义的。在开发时,chrome还远远不够,现在占到了站点用户的7%。在chrome出现之前,它在包括safari在内的所有浏览器中都能正常工作,因此它不是webkit的问题。是的,我知道它可能需要重构,但希望有一个更简单的解决方案(或者说chrome会像其他人一样修复这个问题)。目前,我可能不得不在所有对象属性前面加上_uu或其他东西,以强制自然的定义顺序。我不同意“修复”这个词:Chrome在这里没有什么需要修复的。使用
数组
。我之所以不使用数组,是因为整数数组键会影响数组长度<代码>变量大小=[];尺寸['8']=“条形”->导致空值0-7和长度更改。基本上,我是在寻找关联数组函数
<?php 
$origArray = valueReturnedFromFunction();
$preservedOrder = array_keys($origArray);
?>
<script>
var origArray = <?php echo json_encode($origArray)?>;
var preservedOrder = <?php echo json_encode($preservedOrder )?>;

for(i in preservedOrder){
    var item = origArray[i];
    ...
}
</script>