Вывод: будет напечатано пять раз число 555. Причина (кратко): переменная `var i` — function-scoped, замыкания внутри `setTimeout` ссылаются на одну и ту же переменную `i`. К моменту выполнения коллбеков (после ~100100100 мс) цикл завершён и `i === 5`, поэтому все коллбеки увидят 555. Как исправить (варианты): 1) Использовать `let` (блоковая область видимости, для каждой итерации своё `i`): ```js for (let i = 0; i < 5; i++) { setTimeout(function(){ console.log(i); }, 100); } ``` Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4. 2) Замыкание через IIFE (захватить значение в параметре): ```js for (var i = 0; i < 5; i++) { (function(j){ setTimeout(function(){ console.log(j); }, 100); })(i); } ``` Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4. 3) Передача аргумента в `setTimeout` (поддерживается в современных окружениях): ```js for (var i = 0; i < 5; i++) { setTimeout(function(j){ console.log(j); }, 100, i); } ``` Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4. 4) `bind` для фиксации аргумента: ```js for (var i = 0; i < 5; i++) { setTimeout(console.log.bind(console, i), 100); } ``` Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4. Коротко: проблема в области видимости `var` и асинхронности; лучший современный способ — использовать `let`.
Причина (кратко): переменная `var i` — function-scoped, замыкания внутри `setTimeout` ссылаются на одну и ту же переменную `i`. К моменту выполнения коллбеков (после ~100100100 мс) цикл завершён и `i === 5`, поэтому все коллбеки увидят 555.
Как исправить (варианты):
1) Использовать `let` (блоковая область видимости, для каждой итерации своё `i`):
```js
for (let i = 0; i < 5; i++) {
setTimeout(function(){ console.log(i); }, 100);
}
```
Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4.
2) Замыкание через IIFE (захватить значение в параметре):
```js
for (var i = 0; i < 5; i++) {
(function(j){
setTimeout(function(){ console.log(j); }, 100);
})(i);
}
```
Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4.
3) Передача аргумента в `setTimeout` (поддерживается в современных окружениях):
```js
for (var i = 0; i < 5; i++) {
setTimeout(function(j){ console.log(j); }, 100, i);
}
```
Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4.
4) `bind` для фиксации аргумента:
```js
for (var i = 0; i < 5; i++) {
setTimeout(console.log.bind(console, i), 100);
}
```
Вывод: 0,1,2,3,40, 1, 2, 3, 40,1,2,3,4.
Коротко: проблема в области видимости `var` и асинхронности; лучший современный способ — использовать `let`.