当迭代对象的属性时,在for-in循环中删除它们是否安全?
例如:
for (var key in obj) {
if (!obj.hasOwnProperty(key)) continue;
if (shouldDelete(obj[key])) {
delete obj[key];
}
}
在许多其他语言中迭代数组或字典并删除内部不安全。在JS中可以吗?
(我正在使用Mozilla的Spidermonkey运行时。)
答案 0 :(得分:99)
ECMAScript 5.1 standard部分12.6.4(关于for-in循环)说:
枚举期间可以删除要枚举的对象的属性。如果属性 枚举期间尚未访问的内容将被删除,然后将不会被访问。如果有新属性 添加到枚举期间枚举的对象中,不保证新添加的属性 在活动枚举中访问。在任何枚举中不得多次访问属性名称。
所以我认为OP的代码很合法,并且可以按预期工作。浏览器怪癖一般会影响迭代顺序和删除语句,但不会影响OP代码是否有效。通常最好只删除迭代中的当前属性 - 删除对象中的其他属性将不可预测地导致它们被包含(如果已经访问过)或不包含在迭代中,尽管这可能是也可能不是一个问题,取决于情况。
另见:
但这些都不会影响OP的代码。
答案 1 :(得分:15)
来自Javascript/ECMAScript specification(具体为12.6.4 The for-in Statement):
可以在删除期间删除要枚举的对象的属性 枚举即可。如果是期间尚未访问过的房产 枚举被删除,然后它将不被访问。如果有新属性 枚举期间枚举的对象被添加到中 无法保证在活动状态中访问添加的属性 枚举。任何属性名称都不得多次访问 枚举。