È sicuro eliminare una proprietà di un oggetto durante l'iterazione su di essi?


100

Quando si itera sulle proprietà di un oggetto, è sicuro eliminarli durante un ciclo for-in?

Per esempio:

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

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

In molte altre lingue l'iterazione su un array o un dizionario e l'eliminazione all'interno di ciò non è sicuro. Va bene in JS?

(Sto usando il runtime Spidermonkey di Mozilla.)


Ho iniziato una taglia su questa domanda perché penso che la risposta attuale sia inadeguata e non risponda alla domanda come presentata . Includere anche una fonte pertinente (si spera dalla specifica) e qualsiasi "stranezza" del browser degna di nota, se applicabile.
user2864740

Risposte:


116

La sezione 12.6.4 dello standard ECMAScript 5.1 (sui cicli for-in) dice:

Le proprietà dell'oggetto da enumerare possono essere eliminate durante l'enumerazione. Se una proprietà che non è stata ancora visitata durante l'enumerazione viene eliminata, non verrà visitata. Se vengono aggiunte nuove proprietà all'oggetto da enumerare durante l'enumerazione, non è garantito che le proprietà appena aggiunte vengano visitate nell'enumerazione attiva. Un nome di proprietà non deve essere visitato più di una volta in qualsiasi enumerazione.

Quindi penso che sia chiaro che il codice dell'OP è legale e funzionerà come previsto. Le stranezze del browser influenzano l'ordine di iterazione e cancellano le istruzioni in generale, ma non se il codice OP funzionerà. In genere è meglio eliminare solo la proprietà corrente nell'iterazione: l'eliminazione di altre proprietà nell'oggetto causerà in modo imprevedibile che vengano incluse (se già visitate) o non incluse nell'iterazione, sebbene ciò possa o meno essere un problema a seconda del situazione.

Guarda anche:

Nessuno di questi influisce davvero sul codice dell'OP.


1
Ho appena notato di aver incluso la stessa citazione degli standard dell'altra risposta, scuse.
Domani

17

Dalla specifica Javascript / ECMAScript (in particolare 12.6.4 L'istruzione for-in ):

Le proprietà dell'oggetto da enumerare possono essere eliminate durante l'enumerazione . Se una proprietà che non è stata ancora visitata durante l'enumerazione viene eliminata, non verrà visitata. Se vengono aggiunte nuove proprietà all'oggetto da enumerare durante l'enumerazione, non è garantito che le proprietà appena aggiunte vengano visitate nell'enumerazione attiva . Un nome di proprietà non deve essere visitato più di una volta in qualsiasi enumerazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.