JavaScript中如何实现for...in循环?

3

我看到一个关于for...in语句迭代顺序的问题,并警告说不能信任顺序。在JavaScript引擎中,当前和已访问节点的迭代和跟踪是如何内部完成的?它们之间有什么不同?


这篇相关的帖子可能会提供一些见解https://dev59.com/AXVC5IYBdhLWcg3weBE- - lostsource
2个回答

3
MDN的for...in文档(强调添加)中可以看出:

以任意顺序迭代对象的可枚举属性。

我相信在JavaScript引擎中,内部细节会有所不同,甚至在任何特定引擎的版本之间也可能不同。我猜想,在许多引擎中,它是通过某种哈希表实现的。由于哈希函数会重新排列键,随着哈希表的增长,例如属性ab的相对顺序可能会因添加一个新属性c而改变,而无需更改引擎或其他任何内容。

0

看起来,Object.keys()Object.defineProperties的实现应该模仿for...in的行为:

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

因此它们可以用作参考。

delete运算符也可能会使事情复杂:

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

原型链中的名称冲突也可能会出现问题:

枚举对象的属性包括递归地枚举其原型、原型的原型等属性;但是,如果原型链中的某个先前对象具有相同名称的属性,则不会枚举原型的属性。在确定原型对象的属性是否被原型链上的先前对象遮蔽时,不考虑[[Enumerable]]属性的值。 参考资料

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接