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

JavascriptLoopsObjectProperties

Javascript Problem Overview


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

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?

(I am using Mozilla's Spidermonkey runtime.)

Javascript Solutions


Solution 1 - Javascript

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

> 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.

See also:

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

Solution 2 - Javascript

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

> 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoe ShawView Question on Stackoverflow
Solution 1 - JavascriptTomWView Answer on Stackoverflow
Solution 2 - JavascriptChillView Answer on Stackoverflow