Безопасно ли удалять свойство объекта во время итерации по ним? - PullRequest
87 голосов
/ 12 августа 2010

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

Например:

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

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

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

(я использую Mozilla Spidermonkey Runtime.)

Ответы [ 2 ]

100 голосов
/ 24 октября 2013

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

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

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

Смотри также:

Ничто из этого не влияет на код OP.

15 голосов
/ 24 октября 2013

Из спецификации Javascript / ECMAScript (в частности, 12.6.4 Оператор for-in ):

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

...