Что выведется в 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.