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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3463048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:14:55  来源:igfitidea点击:

Is it safe to delete an object property while iterating over them?

javascriptloopsobjectproperties

提问by Joe Shaw

When iterating over an object's properties, is it safe to delete them while in a for-in loop?

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

For example:

例如:

for (var key in obj) {
    if (!obj.hasOwnProperty(key)) continue;

    if (shouldDelete(obj[key])) {
        delete obj[key];
    }
}

In many other languages iterating over an array or dictionary and deleting inside that is unsafe. Is it okay in JS?

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

(I am using Mozilla's Spidermonkey runtime.)

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

回答by TomW

The ECMAScript 5.1 standardsection 12.6.4 (on for-in loops) says:

ECMAScript的5.1标准节12.6.4(上,中环路)说:

Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.

被枚举对象的属性可能会在枚举过程中被删除。如果在枚举期间尚未访问的属性被删除,则不会访问它。如果在枚举期间向被枚举的对象添加了新属性,则不能保证在活动枚举中访问新添加的属性。在任何枚举中,不能多次访问属性名称。

So I think it's clear that the OP's code is legal and will work as expected. Browser quirks affect iteration order and delete statements in general, but not whether the OPs code will work. It's generally best only to delete the current property in the iteration - deleting other properties in the object will unpredictably cause them to be included (if already visited) or not included in the iteration, although that may or may not be a concern depending on the situation.

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

See also:

也可以看看:

None of these really affects the OP's code though.

不过,这些都不会真正影响 OP 的代码。

回答by Chill

From the Javascript/ECMAScript specification(specifically 12.6.4 The for-in Statement):

来自Javascript/ECMAScript 规范(特别是12.6.4 For-in 语句):

Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. A property name must not be visited more than once in any enumeration.

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