Что выведется в console.log([arr[0](), arr[0]()])?
Дан код:
let i = 10, arr = [];
while (i--) {
arr.push(() => i + i);
}
console.log([arr[0](), arr[0]()]);
Что выведет console.log?
Теория по задаче
Давай разберемся, почему выводится именно такой результат. Для начала рассмотрим, как работает цикл while и замыкание функций в JavaScript.
Понимание замыкания
Задача показывает поведение замыканий в JavaScript.
Замыкание в JavaScript — это функция, которая имеет доступ к переменным из своей внешней (родительской) области видимости, даже после того, как эта внешняя функция завершилась. Оно позволяет сохранять и использовать переменные, созданные в функции, даже после выхода из неё.
Когда создается массив функций (arr), каждая функция замыкается вокруг текущего значения переменной i, которая изменяется в каждой итерации цикла.
Циклическое создание функций
При каждом проходе цикла создается новая анонимная функция, которая ссылается на значение переменной i. Важно отметить, что несмотря на изменение значений i в процессе выполнения цикла, сами функции получают ссылку на одну и ту же переменную i.
while (i--) {
arr.push(() => i + i);
}
Здесь каждый элемент массива представляет собой функцию, возвращающую удвоенное значение переменной i, но поскольку все функции ссылаются на одну и ту же переменную i, результат будет одинаковым вне зависимости от момента создания функции.
Последнее состояние переменной i
Цикл останавливается, когда условие становится ложным, то есть когда i достигает нуля и далее становится отрицательным числом (i--). После завершения цикла значение переменной i остается равным -1.
Вычисление результата
Теперь, когда мы понимаем, что все функции используют одно и то же значение переменной i, вычислим результат выражения:
console.log([arr[0](), arr[0]()]);
Поскольку i === -1, выражение i + i возвращает -2. Следовательно, оба вызова функции вернут -2.