繰り返し処理中にオブジェクトプロパティを削除しても安全ですか?


100

オブジェクトのプロパティを反復処理するとき、for-inループ内でそれらを削除しても安全ですか?

例えば:

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

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

他の多くの言語では、配列または辞書を繰り返し処理し、その内部を削除することは安全ではありません。JSでは大丈夫ですか?

(私はMozillaのSpidermonkeyランタイムを使用しています。)


現在の答えは不十分であり、提示された質問には答えないので、私はこの質問に報奨金を開始しました。関連する情報源(できれば仕様から)と、該当する場合は注目すべきブラウザーの「癖」も含めてください。
user2864740 2013年

回答:


116

ECMAScriptの5.1標準(のためのインループ上の)セクション12.6.4氏は述べています:

列挙されているオブジェクトのプロパティは、列挙中に削除される場合があります。列挙中にまだ訪問されていないプロパティが削除された場合、そのプロパティは訪問されません。列挙中に列挙されているオブジェクトに新しいプロパティが追加された場合、新しく追加されたプロパティがアクティブな列挙でアクセスされるとは限りません。列挙内でプロパティ名に2回以上アクセスすることはできません。

したがって、OPのコードが合法であり、期待どおりに機能することは明らかです。ブラウザーの癖は一般に反復順序と削除ステートメントに影響しますが、OPsコードが機能するかどうかには影響しません。一般的には、反復で現在のプロパティを削除することのみが最善です。オブジェクトの他のプロパティを削除すると、予期せずそれらが含まれ(すでにアクセスされている場合)、反復に含まれません。ただし、状況。

以下も参照してください。

ただし、これらはどれも実際にはOPのコードに影響を与えません。


1
他の回答と同じ標準の引用を含めたことに気づきました。お詫びします。
TomW 2013年

17

以下からのJavascript / ECMAScript仕様(特に12.6.4用-で声明):

列挙されているオブジェクトのプロパティは、列挙中に削除される場合があります。列挙中にまだ訪問されていないプロパティが削除された場合、そのプロパティは訪問されません。列挙中に列挙されているオブジェクトに新しいプロパティが追加された場合、新しく追加されたプロパティがアクティブな列挙でアクセスされるとは限りません。列挙内でプロパティ名に2回以上アクセスすることはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.