Ist es sicher, eine Objekteigenschaft zu löschen, während Sie sie durchlaufen?

100

Ist es sicher, wenn Sie die Eigenschaften eines Objekts durchlaufen, diese in einer For-In-Schleife zu löschen?

Beispielsweise:

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

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

In vielen anderen Sprachen ist es unsicher, ein Array oder Wörterbuch zu durchlaufen und darin zu löschen. Ist es in JS in Ordnung?

(Ich verwende Mozillas Spidermonkey-Laufzeit.)

Joe Shaw
quelle
Ich habe eine Prämie für diese Frage gestartet, weil ich denke, dass die aktuelle Antwort unzureichend ist und die gestellte Frage nicht beantwortet . Bitte geben Sie auch eine relevante Quelle (hoffentlich aus der Spezifikation) und gegebenenfalls alle bemerkenswerten "Macken" des Browsers an.
user2864740

Antworten:

116

Der ECMAScript 5.1-Standardabschnitt 12.6.4 (für For-In-Schleifen) lautet:

Die Eigenschaften des aufzuzählenden Objekts können während der Aufzählung gelöscht werden. Wenn eine Eigenschaft, die während der Aufzählung noch nicht besucht wurde, gelöscht wird, wird sie nicht besucht. Wenn dem Objekt, das während der Aufzählung aufgelistet wird, neue Eigenschaften hinzugefügt werden, kann nicht garantiert werden, dass die neu hinzugefügten Eigenschaften in der aktiven Aufzählung besucht werden. Ein Eigenschaftsname darf in keiner Aufzählung mehr als einmal besucht werden.

Ich denke, es ist klar, dass der OP-Code legal ist und wie erwartet funktioniert. Browser-Macken wirken sich im Allgemeinen auf die Iterationsreihenfolge und das Löschen von Anweisungen aus, nicht jedoch darauf, ob der OP-Code funktioniert. Im Allgemeinen ist es am besten, nur die aktuelle Eigenschaft in der Iteration zu löschen. Wenn Sie andere Eigenschaften im Objekt löschen, werden sie unvorhersehbar in die Iteration aufgenommen (falls sie bereits besucht wurden) oder nicht, obwohl dies je nach Lage.

Siehe auch:

Nichts davon wirkt sich jedoch wirklich auf den Code des OP aus.

TomW
quelle
1
Ich habe gerade bemerkt, dass ich das gleiche Standardzitat wie die andere Antwort beigefügt habe, Entschuldigung.
TomW
17

Aus der Javascript / ECMAScript-Spezifikation (speziell 12.6.4 The for-in Statement ):

Die Eigenschaften des aufzuzählenden Objekts können während der Aufzählung gelöscht werden . Wenn eine Eigenschaft, die während der Aufzählung noch nicht besucht wurde, gelöscht wird, wird sie nicht besucht. Wenn dem Objekt, das während der Aufzählung aufgelistet wird, neue Eigenschaften hinzugefügt werden, kann nicht garantiert werden, dass die neu hinzugefügten Eigenschaften in der aktiven Aufzählung besucht werden . Ein Eigenschaftsname darf in keiner Aufzählung mehr als einmal besucht werden.

Ausruhen
quelle