Чи безпечно видаляти властивість об'єкта під час ітерації над ними?


100

Чи можна безпечно видаляти їх під час ітерації властивостей об'єкта, перебуваючи у циклі для входу?

Наприклад:

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

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

У багатьох інших мовах ітерація над масивом чи словником та видалення всередині це небезпечно. Чи добре в JS?

(Я використовую середовище виконання Spidermonkey від Mozilla.)


Я розпочав щедрувати з цього питання, тому що вважаю, що нинішня відповідь є неадекватною і не відповідає на поставлене запитання . Будь ласка, включіть відповідне джерело (сподіваємось із специфікації) та будь-які помітні веб-переглядачі браузера, якщо це можливо.
користувач2864740

Відповіді:


116

ECMAScript 5.1 стандартний розділ 12.6.4 (на за-петлях) говорить:

Властивості об'єкта, який перераховується, можуть бути видалені під час перерахування. Якщо майно, яке ще не було відвідано під час перерахування, буде видалено, воно не буде відвідуватися. Якщо до об’єкту, який перераховується під час перерахування, додаються нові властивості, щойно додані властивості не будуть гарантовано відвідуватися в активному перерахуванні. Ім’я власності не повинно відвідуватися більше одного разу в будь-якому перерахунку.

Тож я думаю, що зрозуміло, що код ОП є законним і працюватиме так, як очікувалося. Вигадки браузера впливають на порядок ітерації та видалення операторів загалом, але не те, чи спрацює код ОП. Як правило, найкраще лише видалити поточне властивість під час ітерації - видалення інших властивостей об'єкта непередбачувано спричинить їх включення (якщо вже відвідане) або не включення в ітерацію, хоча це може викликати або не викликати занепокоєння залежно від ситуація.

Дивитися також:

Жодне з них насправді не впливає на код OP.


1
Я щойно помітив, що я включив ті ж цитати стандартів, що й інші відповіді, вибачення.
TomW

17

З специфікації Javascript / ECMAScript (зокрема 12.6.4 Заява про вхід ):

Властивості об'єкта, який перераховується, можуть бути видалені під час перерахування . Якщо майно, яке ще не було відвідано під час перерахування, буде видалено, воно не буде відвідуватися. Якщо до об'єкта, який перераховується під час перерахування, додаються нові властивості , щойно додані властивості не будуть гарантовано відвідуватися в активному перерахуванні . Ім’я власності не повинно відвідуватися більше одного разу в будь-якому перерахунку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.