迭代它们时删除对象属性是否安全?

在迭代对象的属性时,在for-in循环中删除它们是否安全?

例如:

for (var key in obj) { if (!obj.hasOwnProperty(key)) continue; if (shouldDelete(obj[key])) { delete obj[key]; } } 

在许多其他语言迭代数组或字典和删除里面是不安全的。 在JS中可以吗?

(我正在使用Mozilla的Spidermonkey运行时。)

ECMAScript 5.1标准第12.6.4节(在for循环中)说:

被列举的对象的属性可能会在枚举过程中被删除。 如果枚举过程中尚未访问的属性被删除,则不会被访问。 如果在枚举过程中将新属性添加到枚举对象中,则新增属性不保证在活动枚举中被访问。 枚举中不得多次访问属性名称。

所以我认为OP的代码是合法的,并且会按预期工作。 浏览器怪异会影响迭代顺序和删除语句,但不会影响OP代码是否工作。 通常最好的做法是只删除迭代中的当前属性 – 删除对象中的其他属性将导致它们被包含(如果已经被访问过)或者不包含在迭代中,尽pipe这可能是也可能不是一个问题,取决于情况。

也可以看看:

  • MDN上for..in
  • MDN浏览器怪癖:重复顺序
  • 在深入页面上删除操作员问题

这些都不影响OP的代码。

从Javascript / ECMAScript规范 (特别是12.6.4 for-in语句 ):

被列举的对象的属性可能会在枚举过程中被删除 。 如果枚举过程中尚未访问的属性被删除,则不会被访问。 如果在枚举过程中将新属性添加到枚举对象中,则新增属性不保证在活动枚举中被访问 。 枚举中不得多次访问属性名称。