for
относится к низкоуровневым циклам. Он требует задания счетчика, правил его изменения и условия остановки. Было бы значительно удобнее обходить элементы коллекции напрямую, без счетчика. Многие языки программирования решают это введением специального вида цикла. В JavaScript тоже есть такой: for...of
.
const userNames = ['petya', 'vasya', 'evgeny'];
// name на каждой итерации свой собственный (локальный), поэтому используется const
for (const name of userNames) {
console.log(name);
}
// => "petya"
// => "vasya"
// => "evgeny"
https://repl.it/@hexlet/js-arrays-for-of-example
Как видно из примера, код, использующий for...of
, получается значительно чище, чем с использованием цикла for
. for...of
знает о том, как перебирать элементы и знает о том, когда они закончатся. Поэтому счетчик не используется, а вместо доступа к элементу по индексу, например userNames[i]
, в цикле создается переменная const name
. На каждой итерации она принимает значение элемента массива userNames
, область видимости константы ограничена телом цикла.
Этот цикл отлично подходит для задач агрегации:
const calculateSum = (coll) => {
let sum = 0;
for (const value of coll) {
sum += value;
}
return sum;
};
for...of
— это больше, чем просто цикл для массивов. Для полного понимания принципов его работы, нужно разбираться в темах, которые мы еще не проходили, среди них объекты, упаковка/распаковка и итераторы. Если по-простому, то разные данные в JavaScript могут притворяться коллекциями элементов. Самый простой пример — это строка: for...of
перебирает строку посимвольно.
const greeting = 'Hello';
// В этот момент со строкой происходит магия, которая разбирается в курсе ООП
for (const symbol of greeting) {
console.log(symbol);
}
// => "H"
// => "e"
// => "l"
// => "l"
// => "o"
Однако не следует путать строку с массивом. Несмотря на внешнюю схожесть доступа к элементам строки по индексу, строка массивом не является.
Применимость
В большинстве задач, использующих цикл, предпочтительнее for...of
. Иногда его бывает недостаточно, и требуется ручное управление обходом. В таких случаях можно возвращаться к использованию for
. Например, когда нужно идти не по каждому элементу массива, а через один:
for (let i = 0; i < items.length; i += 2) {
// какой-то код
}
Иногда нужно обходить массив в обратном порядке. for...of
здесь бессилен и снова нужен for
:
for (let i = items.length - 1; i >= 0; i -= 1) {
// какой-то код
}
Другие задачи вообще с массивами напрямую не связаны. К последним относятся ситуации, когда нужно перебирать числа в определенном диапазоне. В этом случае нет массива, по которому можно было бы пройтись с помощью for...of
.
for (let i = 5; i < 10; i += 1) {
// какой-то код
}
Ну и наконец, встречаются задачи, в которых нужно во время обхода менять исходный массив:
for (let i = 0; i < items.length; i += 1) {
items[i] = /* что-то делаем */
}
Если заглядывать в будущее и в то, как пишется реальный код на JavaScript, то там появляются функции высшего порядка. То есть на практике циклы, можно сказать, не нужны за редким исключением. Однако, невозможно перепрыгнуть работу с циклами, так как это база. А функции высшего порядка требуют понимания таких тем, которые за один присест не изучаются.
Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.