Классический цикл for в javascript состоит из 3х операторов: init, predicate, nextIteration
В общей записи это выглядит так:
for(init; predicate; nextIteration) { body }
Цикл for исполняется следующим образом:
1. Выполняется оператор init в области видимости блока цикла
Обычно здесь объявляют переменную-счетчик и присваивают ей начальное значение
Определение "в области видимости блока цикла" означает, что если init-оператор представляет собой оператор let - то объявленные переменные будут видны в цикле, но не за его пределами
2. Вычисляется predicate, его результат приводится к boolean и последующее выполнение зависит от результата этого приведения:
Если результат === false - то цикл завершается
Если результат === true - то переходим к шагу
33. Исполняется тело цикла - блок body, официально блоком быть не обязан, может быть и единичным оператором, но лучше всегда писать блок (фигурные скобки)
4. Исполняется оператор nextIteration и переходим к пункту
2
Теперь разберемся на конкретных примерах:
Прямой циклfor(let i = 0; i < 10; i++) {
console.log(i);
}
Объявляется переменная i и ей присваивается начальное значение 0
Получается результат выражения Boolean(i < 10) -> 0 < 10 - true -> Boolean(true) - true -> можем выполнять тело
Выполняется тело console.log(i); -> видим 0 в консольке
Выполняется i++ -> i становится 1
Получается результат выражения Boolean(i < 10) -> 1 < 10 - true -> Boolean(true) - true -> можем выполнять тело
...
Так все продолжается 10 раз, на 10 итерации появляются изменения после этого момента:
Выполняется i++ -> i становится 10
олучается результат выражения Boolean(i < 10) -> 10 < 10 - false -> Boolean(false) - false -> завершаем цикл
инвертированный циклfor(let i = 10; i--;) {
console.log(i);
}
Объявляется переменная i и ей присваивается начальное значение 10
Получается результат выражения Boolean(i--) -> i-- - 10, i = 9 -> Boolean(10) - true -> можем выполнять тело
Выполняется тело console.log(i); -> видим 9 в консольке
Оператор nextIteration - пустой, ничего выполнять не надо
Получается результат выражения Boolean(i--) -> i-- - 9, i = 8 -> Boolean(9) - true -> можем выполнять тело
...
Цикл по прежнему работает 10 раз, последняя итерация (когда i к моменту исполнения predicate равна 0):
Получается результат выражения Boolean(i--) -> i-- - 0, i = -1 -> Boolean(0) - false -> завершаем цикл
Как видим, за счет отсутствия nextIteration оператора, на каждой итерации выполняется на одно действие меньше, поэтому цикл отрабатывает быстрее