, но она в корне отличается от инструкции обычного цикла
for
. Цикл
for/in
имеет следующий синтаксис:
for (переменная in объект)
инструкция
В качестве переменной здесь обычно используется имя переменной, но точно так же можно использовать любое выражение, возвращающее левостороннее выражение (раздел 4.7.3),
или инструкцию
var
, объявляющую единственную переменную, - практически все, что может находиться слева от оператора присваивания. Параметр объект - это выражение, возвращающее объект. И как обычно, инструкция - это инструкция или блок инструкций, образующих тело цикла.
Для обхода элементов массива естественно использовать обычный цикл
for
:
for(var і = 0; і < a.length; і++) // Присваивать индексы в массиве переменной і
console.log(a[і]); // Вывести значение каждого элемента массива
Инструкция for/in так же естественно позволяет выполнить обход свойств объекта.
for(var р in о) // Присваивать имена свойств объекта о переменной р
console.log(o[p]); // Вывести значение каждого свойства
Чтобы выполнить инструкцию
for/in
, интерпретатор JavaScript сначала вычисляет выражение объект. Если оно возвращает значение
null
или
undfefined
, интерпретатор пропускает цикл и переходит к следующей инструкции. [6] (Реализации, следующие стандарту ECMAScript 3, в этом случае могут возбуждать исключение
ТуреЕггог
.) Если выражение возвращает простое значение, оно преобразуется в эквивалентный объект-обертку (раздел 3.6). В противном случае выражение возвращает объект. Затем интерпретатор выполняет по одной итерации цикла для каждого перечислимого свойства объекта. Перед каждой итерацией интерпретатор вычисляет значение выражения переменная и присваивает ему имя свойства (строковое значение).
6
Реализации, следующие стандарту ECMAScript 3, в этом случае могут возбуждать исключение ТуреЕrror.
Обратите внимание, что переменная в цикле
for/in
может быть любым выражением, возвращающим значение, которое можно использовать слева от оператора присваивания. Это выражение вычисляется в каждой итерации цикла, т. е. каждый раз оно может возвращать разные значения. Например, чтобы скопировать имена всех свойств объекта в массив, можно использовать следующий цикл:
var о = {х:1. у:2. z:3};
var а = [];
var і = 0;
for(a[i++] in о) /* пустое тело цикла */;
Массивы в JavaScript - это просто специальный тип объектов, а индексы в массиве - свойства объекта, обход которых можно выполнить с помощью цикла
for/in
. Например, следующая инструкция перечислит индексы 0, 1 и 2 массива, объявленного выше:
fоr(і in a) console.log(i);
В действительности цикл
for/in
может совершать обход не по всем свойствам объекта, а только по перечислимым свойствам (раздел 6.7).
Многочисленные встроенные методы, определяемые в базовом языке JavaScript, не являются перечислимыми. Например, все объекты имеют метод
toString
, но цикл
for/in
не перечислит свойство
toString
. Кроме встроенных методов также не являются перечислимыми многие другие свойства встроенных объектов. При этом все свойства и методы, определяемые пользователем, являются перечислимыми. (Но в реализации, следующей стандарту ECMAScript 5, имеется возможность сделать их неперечислимыми, использовав прием, описанный в разделе 6.7.) Унаследованные свойства, которые были определены пользователем (раздел 6.2.2), также перечисляются циклом for/in.
Если в теле цикла
for/in
удалить свойство, которое еще не было перечислено, это свойство перечислено не будет. Если в теле цикла создать новые свойства, то обычно такие свойстве не будут перечислены. (Однако некоторые реализации могут перечислять унаследованные свойства, добавленные в ходе выполнения цикла.)
5.5.4.1. Порядок перечисления свойств
Спецификация ECMAScript не определяет порядок, в каком цикл
for/in
должен перечислять свойства объекта. Однако на практике реализации JavaScript во всех основных броузерах перечисляют свойства простых объектов в порядке, в каком они были определены, - когда ранее объявленные свойства перечисляются первыми. Если объект был создан с помощью литерала объекта, свойства перечисляются в том же порядке, в каком они следуют в литерале. В Интернете существуют сайты и библиотеки, которые опираются на такой порядок перечисления, поэтому маловероятно, что производители броузеров изменят его.
В абзаце выше описывается описывается порядок перечисления свойств "простых" объектов. Однаков разных реализациях порядок перечисления может отличаться, если:
• объект наследует перечислимые свойства;
• объект имеет свойства, которые являются целочисленными индексами массива;
• использовалась инструкция
delete
для удаления существующих свойств объекта или
• использовался метод
Object.defineProperty
(раздел 6.7) или аналогичный ему для изменения атрибутов свойства объекта.
Обычно (но не во всех реализациях) унаследованные свойства (раздел 6.2.2) перечисляются после всех неунаследованных, «собственных» свойств объекта, но они также перечисляются в порядке их определения. Если объект наследует свойства более чем от одного «прототипа» (раздел 6.1.3) - например, когда в его «цепочке прототипов» имеется более одного объекта, - свойства каждого объекта-прототипа в цепочке перечисляются в порядке их создания перед перечислением свойств следующего объекта. Некоторые (но не все) реализации перечисляют свойства массива в порядке возрастания чисел, а не в порядке их создания, но при наличии в массиве свойств с нечисловыми именами происходит возврат к перечислению в порядке создания свойств, то же самое происходит и в случае разреженных массивов (т. е. когда в массиве отсутствуют некоторые элементы).
5.6. Переходы
Еще одной категорией инструкций языка JavaScript являются инструкции перехода. Как следует из названия, эти инструкции заставляют интерпретатор JavaScript переходить в другое место в программном коде. Инструкция
break
заставляет интерпретатор перейти в конец цикла или другой инструкции. Инструкция
continue
заставляет интерпретатор пропустить оставшуюся часть тела цикла, перейти обратно в начало цикла и приступить к выполнению новой итерации. В языке JavaScript имеется возможность помечать инструкции именами, благодаря чему в инструкциях
break
и
continue
можно явно указывать, к какому циклу или к какой другой инструкции они относятся.