web-dev-qa-db-fra.com

Est-il sûr de supprimer une propriété d'objet tout en itérant sur eux?

Lors de l'itération sur les propriétés d'un objet, est-il sûr de les supprimer dans une boucle for-in?

Par exemple:

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

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

Dans de nombreuses autres langues, itérer sur un tableau ou un dictionnaire et supprimer à l'intérieur n'est pas sûr. Est-ce que ça va dans JS?

(J'utilise le runtime Spidermonkey de Mozilla.)

94
Joe Shaw

ECMAScript 5.1 standard section 12.6.4 (sur les boucles for-in) dit:

Les propriétés de l'objet énuméré peuvent être supprimées pendant l'énumération. Si une propriété qui n'a pas encore été visitée pendant l'énumération est supprimée, elle ne sera pas visitée. Si de nouvelles propriétés sont ajoutées à l'objet en cours d'énumération pendant l'énumération, les propriétés nouvellement ajoutées ne sont pas garanties d'être visitées dans l'énumération active. Un nom de propriété ne doit pas être visité plus d'une fois dans une énumération.

Je pense donc qu'il est clair que le code du PO est légal et fonctionnera comme prévu. Les bizarreries du navigateur affectent l'ordre d'itération et les instructions de suppression en général, mais pas le fonctionnement du code OP. Il est généralement préférable de supprimer la propriété actuelle dans l'itération - la suppression d'autres propriétés dans l'objet entraînera de manière imprévisible leur inclusion (si elles ont déjà été visitées) ou leur non-inclusion dans l'itération, bien que cela puisse ou non être un problème en fonction de la situation.

Voir également:

Cependant, aucun de ces éléments n'affecte vraiment le code de l'OP.

108
TomW

De la spécification Javascript/ECMAScript (spécifiquement 12.6.4 La déclaration for-in ):

Les propriétés de l'objet en cours d'énumération peuvent être supprimées pendant l'énumération . Si une propriété qui n'a pas encore été visitée pendant l'énumération est supprimée, elle ne sera pas visitée. Si de nouvelles propriétés sont ajoutées à l'objet en cours d'énumération pendant l'énumération, les propriétés nouvellement ajoutées ne sont pas garanties d'être visitées dans l'énumération active. Un nom de propriété ne doit pas être visité plus d'une fois dans une énumération.

17
Chill