Firefox中的Javascript自动排序vs其他浏览器

时间:2014-01-09 18:13:10

标签: javascript firefox

最近我在Firefox中发现了这种奇怪的行为:

此代码自动对属性进行排序:

var an_obj = { "4": "d", "1": "a", "2": "c"};
alert(Object.keys(an_obj)); // will alert "1, 2, 4"

虽然这不是:

var value2 = {"1003":1, "1001":2, "1000":3};
alert(Object.keys(value2));// will alert "1003, 1001, 1000"

任何大于1000的数字在Firefox中都会有不同的行为,而其他浏览器(Chrome,IE11)的行为将与预期的自动排序数字大于1000一样。

我相信这是FireFox中的一个错误,我错了吗?

更新1

这使得命令在FireFox的相同实现中“不可预测”。我可以理解不完全排序的数值或相应地排序一个标准,但在“任意”数字之后不会表现为“不可预测”。

4 个答案:

答案 0 :(得分:6)

这不是错误。对象不保证其属性中的任何顺序,并且在某些情况下不应依赖Object.keys的任何顺序。

§15.2.3.14 ECMAScript 5 standard中说明了Object.keys

  

如果实现为for-in语句定义了特定的枚举顺序,则必须在此算法的步骤5中使用相同的枚举顺序。

这意味着for-in语句和Object.keys的任何排序都完全取决于实现。

答案 1 :(得分:2)

ECMAScript standard没有为Object.keys返回的属性定义排序,而是将其留给实现:

  

如果实现定义了枚举的特定顺序   for-in语句,必须在步骤5中使用相同的枚举顺序   这个算法。

至于Firefox使用的具体实现,MDN states

  

属性的顺序与通过手动循环对象的属性给出的顺序相同。

事实上,如果你尝试一下,你会发现情况确实如此:

for(var o in {"1003":1, "1001":2, "1000":3}) 
    console.log(o); 
// 1003, 1001, 1000 

对结果的排序没有其他保证。换句话说,它不是一个错误,它只是不同实现的本质的一部分。但如果你愿意,可以称之为 quirk

答案 2 :(得分:1)

我想添加一个我自己的问题,我发现有人已经将这种行为提交给了Firefox团队:

@Peter Olson和@ p.s.w.g正确解释的答案是:

  

是的,枚举排序未指定。不要依赖它!

ES7应该纠正这个问题,而关于这个问题的最终决定是咬紧牙关并让它无法解决。

对于对此感兴趣的人,您可以在此处找到完整的参考资料:

https://bugzilla.mozilla.org/show_bug.cgi?id=865760

答案 3 :(得分:0)

您可以使用sort来修复不可预测的行为。我假设您已经知道这一点并且正在尝试获取有关可能的错误的反馈,但是如果您没有,或者其他人需要知道:

var value2 = {"1003":1, "1001":2, "1000":3};
var sorted = Object.keys(value2);
sorted.sort();
alert(sorted);

在firefox中以预期的方式呈现值。