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