Дан следующий фрагмент кода на JavaScript: const arr = [1,2,3]; for (var i=0;iconsole.log(i),100); } объясните, что будет выведено и почему, и предложите не менее двух способов изменить код, чтобы получить ожидаемые значения индексов
Выведется трижды число 3\,33. Почему: переменная `i` объявлена через `var` — она имеет функциональную (не блочную) область видимости. Цикл завершится до срабатывания отложенных функций, и к моменту выполнения всех колбэков `i` станет равным длине массива ( 3\,33). Все колбэки читают одно и то же внешнее `i`, поэтому вывод: три строки со значением 3\,33. Ожидаемые значения индексов — 0, 1, 2\,0,\ 1,\ 20,1,2. Несколько способов получить их: 1) Использовать `let` в заголовке цикла (блочная область для каждой итерации): ```js const arr = [1,2,3]; for (let i = 0; i < arr.length; i++) { setTimeout(() => console.log(i), 100); } ``` 2) Создать замыкание через IIFE, фиксируя текущее `i`: ```js const arr = [1,2,3]; for (var i = 0; i < arr.length; i++) { (function(index) { setTimeout(() => console.log(index), 100); })(i); } ``` 3) Передать значение `i` как аргумент в `setTimeout` (поддерживают современные движки): ```js const arr = [1,2,3]; for (var i = 0; i < arr.length; i++) { setTimeout((index) => console.log(index), 100, i); } ``` 4) Привязать значение через `bind`: ```js const arr = [1,2,3]; for (var i = 0; i < arr.length; i++) { setTimeout(console.log.bind(null, i), 100); } ``` Любой из этих вариантов выведет в консоль по очереди 0\,00, 1\,11, 2\,22.
Почему: переменная `i` объявлена через `var` — она имеет функциональную (не блочную) область видимости. Цикл завершится до срабатывания отложенных функций, и к моменту выполнения всех колбэков `i` станет равным длине массива ( 3\,33). Все колбэки читают одно и то же внешнее `i`, поэтому вывод: три строки со значением 3\,33.
Ожидаемые значения индексов — 0, 1, 2\,0,\ 1,\ 20, 1, 2. Несколько способов получить их:
1) Использовать `let` в заголовке цикла (блочная область для каждой итерации):
```js
const arr = [1,2,3];
for (let i = 0; i < arr.length; i++) {
setTimeout(() => console.log(i), 100);
}
```
2) Создать замыкание через IIFE, фиксируя текущее `i`:
```js
const arr = [1,2,3];
for (var i = 0; i < arr.length; i++) {
(function(index) {
setTimeout(() => console.log(index), 100);
})(i);
}
```
3) Передать значение `i` как аргумент в `setTimeout` (поддерживают современные движки):
```js
const arr = [1,2,3];
for (var i = 0; i < arr.length; i++) {
setTimeout((index) => console.log(index), 100, i);
}
```
4) Привязать значение через `bind`:
```js
const arr = [1,2,3];
for (var i = 0; i < arr.length; i++) {
setTimeout(console.log.bind(null, i), 100);
}
```
Любой из этих вариантов выведет в консоль по очереди 0\,00, 1\,11, 2\,22.