【问题标题】:How is for...in implemented in JavaScript?for...in 是如何在 JavaScript 中实现的?
【发布时间】:2012-11-19 20:33:16
【问题描述】:

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

【问题讨论】:

标签: javascript algorithm object cross-browser iteration


【解决方案1】:

来自the MDN documentation for for...in(已添加重点):

以任意顺序遍历对象的可枚举属性。

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

【讨论】:

    【解决方案2】:

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

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

    所以它们可以作为参考。

    delete 运算符也可以使事情复杂化:

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

    原型链中的名称冲突也是如此:

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

    参考文献

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2014-06-09
      • 2018-09-12
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多