Безопасно ли удалять свойство объекта во время итерации по ним?

При повторении по свойствам объекта безопасно ли их удалять во время цикла in-in?

Например:

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

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

Во многих других языках, итерации по массиву или словарю и удаление внутри, это небезопасно. Это нормально в JS?

(я использую среду выполнения Mozilla Spidermonkey.)

Ответ 1

стандарт ECMAScript 5.1, раздел 12.6.4 (для циклов in-in) говорит:

Свойства перечислимого объекта могут быть удалены во время перечисления. Если имущество который еще не был посещен во время перечисления, удаляется, а затем его не посещают. Если новые свойства добавленный к объекту, перечисляемому во время перечисления, вновь добавленные свойства не гарантируются быть посещенным в активном перечислении. Имя свойства не должно посещаться более одного раза в любом перечислении.

Поэтому я думаю, что ясно, что OP-код является законным и будет работать, как ожидалось. Привилегии браузера влияют на порядок итерации и вообще удаляют заявления, но не работает ли код OP. Обычно лучше всего удалить текущее свойство на итерации - удаление других свойств объекта непредсказуемо приведет к их включению (если оно уже посещено) или не включено в итерацию, хотя это может быть или не быть проблемой в зависимости от ситуация.

См. также:

Однако это не влияет на код OP.

Ответ 2

Из спецификации Javascript/ECMAScript (в частности 12.6.4 Заявление in-in):

Свойства перечислимого объекта могут быть удалены во время Перечисление. Если свойство, которое еще не было посещено во время перечисление будет удалено, то оно не будет посещено. Если новые свойства добавляются к объекту, который перечисляется во время перечисления, добавленные свойства не гарантируются для посещения в активном перечисление. Имя свойства нельзя посещать более одного раза в любом перечисление.