虽然不能保证 for..in 循环中的元素顺序,但在实践中实现之间存在啥偏差? [关闭]

Posted

技术标签:

【中文标题】虽然不能保证 for..in 循环中的元素顺序,但在实践中实现之间存在啥偏差? [关闭]【英文标题】:While element ordering in for..in loops isn't guaranteed, what deviation between implementations is there in practice? [closed]虽然不能保证 for..in 循环中的元素顺序,但在实践中实现之间存在什么偏差? [关闭] 【发布时间】:2012-11-06 14:38:42 【问题描述】:

我不记得在哪里,但我曾经看到它提到for..in 循环可以按实现者喜欢的任何顺序遍历元素,包括向前、向后、随机或在每次执行时在向前和向后交替for..in 循环。但是,在实践中,不知何故,我不认为后者确实存在任何实现的情况。 (虽然,我们知道有某个浏览器喜欢搞砸事情,所以你永远不能太确定,但我离题了。)

我的观点是,虽然在实践中for..in 排序可能没有那么严重的偏差,但我想知道 ECMAScript 实现之间存在什么偏差(如果有的话)。我想现在主要的应该是 JScript、Chakra、Futhark、Carakan、javascriptCore、SquirrelFish、V8、SpiderMonkey 和 TraceMonkey,仅供参考。

【问题讨论】:

如果语言规范说不能保证排序,这意味着任何实现都可能在明天改变主意。正确的做法是编写不依赖于不能依赖的东西的代码。 作为参考,我几乎在***.com/a/10587330/319403 中做出了确切的陈述:) @cHao 猜猜这就是我所指的地方。谢谢! :) 【参考方案1】:

首先,这里是规范中关于枚举顺序的参考:

12.6.4 The for-in Statement

未指定枚举属性的机制和顺序(第一个算法中的步骤 6.a,第二个算法中的步骤 7.a)。 被枚举对象的属性可能在枚举过程中被删除。如果在枚举期间还没有访问过的属性被删除,那么它就不会被访问。 如果在枚举过程中向正在枚举的对象添加了新属性,则不保证在活动枚举中访问新添加的属性。在任何枚举中不得多次访问属性名称。

我能想到的只有这些:

早期的(可能是当前的?) 版本的 IE 会将在枚举期间添加的新属性放在枚举的末尾,以便当前运行的for-in 访问它们。

V8 具有不同的枚举顺序,如 this bug report 中所述,它被关闭为 WorkingAsIntended

 var a = "foo":"bar", "3": "3", "2":"2", "1":"1";

在 Firefox 和 V8 中的测试显示了不同的顺序。

这不是一个列表。当然可能还有更多。我认为@Pointy 的评论总结了这一点。没有保证。即使您有一个以一致方式可靠枚举的对象,这并不意味着它会在下一个版本升级时这样做。使用工具来确定它们的工作方式,而不是仅仅看起来工作。

【讨论】:

感谢您,嗯,建设性的回答!我认为在没有真正阅读问题的情况下就结束一个问题是非常不具建设性的。 不客气。我也不确定它是如何“不具建设性”的。询问在实践中是否存在实际变化,以及是否应该依赖for-in 排序似乎确实有效,这似乎是有道理的。任何此类列表都可能很快过时,但核心问题仍然相关。 问题归结为“我何时/到什么程度可以忽略规范”?显而易见的答案是“从不;需要遵循规范”。任何其他答案都将是主观的且值得商榷的,更不用说特定时间了。 @cHao:规范的实现中经常有一些细节是统一的,无论是否包含在规范中。有时这些统一性最终会被包括在内。所以值得一问。 @cHao:在 html5 包含 .innerHTML 之前,你有没有使用过它?

以上是关于虽然不能保证 for..in 循环中的元素顺序,但在实践中实现之间存在啥偏差? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

“for (... in ...)”循环中的元素顺序

javascript中 for in for forEach for of Object.keys().

js for in 和 for of的区别

for-in和for 循环 的区别

JS中的forEach,for in,for of和for的遍历优缺点及区别

for in for of区别