Найдите и объясните ошибку в JavaScript-коде: for (var i = 0; i console.log(i), 100); Почему вывод не соответствует ожидаемому и как исправить код, сохранив поведение таймера
Ошибка в том, что переменная `i` объявлена через `var` (функциональная область видимости), поэтому все три колбэка замыкают одну и ту же переменную `i`. К моменту выполнения таймаутов цикл уже завершён и i=3i = 3i=3, поэтому вывод будет 3,3,33,3,33,3,3, а не ожидаемые 0,1,20,1,20,1,2. Как исправить (сохраняя таймер с задержкой 100100100 мс): 1) Использовать `let` (простое и современное): for (let i = 000; i < 333; i++) setTimeout(() => console.log(i), 100100100); Пояснение: `let` даёт блочную привязку и для каждой итерации создаётся своё `i`. 2) Создать замыкание через IIFE (если нужно поддерживать старый код/ES5): for (var i = 000; i < 333; i++) (function(j){ setTimeout(() => console.log(j), 100100100); })(i); Пояснение: аргумент `j` сохраняет текущее значение `i` для каждого таймера. 3) Передать значение как аргумент в setTimeout: for (var i = 000; i < 333; i++) setTimeout(console.log, 100100100, i); Или с привязкой контекста: for (var i = 000; i < 333; i++) setTimeout(console.log.bind(console, i), 100100100); Пояснение: третий аргумент `setTimeout` передаёт значение в колбэк. Рекомендация: использовать вариант с `let` как наиболее простой и безопасный.
Как исправить (сохраняя таймер с задержкой 100100100 мс):
1) Использовать `let` (простое и современное):
for (let i = 000; i < 333; i++) setTimeout(() => console.log(i), 100100100);
Пояснение: `let` даёт блочную привязку и для каждой итерации создаётся своё `i`.
2) Создать замыкание через IIFE (если нужно поддерживать старый код/ES5):
for (var i = 000; i < 333; i++) (function(j){ setTimeout(() => console.log(j), 100100100); })(i);
Пояснение: аргумент `j` сохраняет текущее значение `i` для каждого таймера.
3) Передать значение как аргумент в setTimeout:
for (var i = 000; i < 333; i++) setTimeout(console.log, 100100100, i);
Или с привязкой контекста:
for (var i = 000; i < 333; i++) setTimeout(console.log.bind(console, i), 100100100);
Пояснение: третий аргумент `setTimeout` передаёт значение в колбэк.
Рекомендация: использовать вариант с `let` как наиболее простой и безопасный.