3

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

4

2 回答 2

3

来自MDN 文档for...in(强调添加):

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

我确信内部细节因 JavaScript 引擎而异,甚至很可能在任何特定引擎的版本之间。我猜在许多引擎中,它是通过某种哈希表实现来完成的。由于哈希函数会随着哈希表的增长对键进行重新排序,因此属性的相对顺序a可以b通过添加新属性来更改c,而无需更改引擎或任何东西。

于 2012-11-19T20:39:30.577 回答
0

似乎Object.keys()and的实现Object.defineProperties应该模仿以下行为for...in

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

所以它们可以作为参考。

操作员还可以使delete事情复杂化:

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

可以命名原型链中的冲突:

枚举对象的属性包括递归地枚举其原型的属性、原型的原型等等;但是如果原型的属性被“隐藏”,则不会枚举它,因为原型链中的某些先前对象具有同名的属性。在确定原型对象的属性是否被原型链上的前一个对象遮蔽时,不考虑 [[Enumerable]] 属性的值。

参考

于 2014-07-15T02:15:07.510 回答