2015-06-14 2 views
0
A = [1,2,3,4,5]; 
for (var i in A) { 
    if (A[i] == 4) A.splice(i,1), A.push(7); 
    if (A[i] == 2) A.splice(i,1), A.push(0); 
    if (A[i] == 7) console.log('seven'); 
    if (A[i] == 0) console.log('zero'); 
} 
console.log(A); 

Это похоже на работу, но я не знаю деталей реализации цикла for (.. in ..), чтобы убедиться, что он безопасен в большинстве условий.Безопасно ли изменять контур Array in for (..in ..)?

See also the paired question about an object modification

+4

Непростая итерация массивов с использованием 'for..in'. – Teemu

+1

[ECMA 262 - заявление 'for-in'] (http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4). Свойства извлекаются по одному, после завершения предыдущей итерации. Итак, если вы спрашиваете, возможно ли изменить объект, чтобы цикл продолжался бесконечно, да, это возможно. –

+0

* Возможно ли? * Да. * Это безопасно? * Да. * Это хорошая практика? * Нет, потому что легко потеряться с индексом, о котором вы говорите. –

ответ

0

Это совершенно безопасно, чтобы изменить объект в том смысле, вы не получите браузер жалуются на каких-либо изменений в массиве. Просто обратите внимание, что в вашем примере все равно было бы правильное поведение, если бы вы видели «семь, ноль», просто «семь», просто «ноль» или вообще ничего не печатали.

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

  • Перечислит новые свойства или пусть их из петли
  • Перечислите свойства по любому заказу.

Вот почему это не безопасно использовать for ... in для перебора массивов, когда зависит от индекса/заказа. Индексы рассматриваются как перечислимые свойства и могут быть перечислены с той же механикой, используемой для свойств объекта (где нет ожиданий по порядку итерации).