Разберите следующий фрагмент на JavaScript: `for (var i = 0; i console.log(i), 0);` — объясните поведение и предложите несколько способов вывести 0,1,2
Что происходит — коротко: - Переменная `i` объявлена через `var`, она функционально (не блочно) область видимости. Цикл выполняется и создаёт три отложенных колбэка, но все они захватывают одну и ту же `i`. К моменту выполнения таймаутов `i` уже равна 333, поэтому в консоль выводится 3,3,33, 3, 33,3,3. Как получить в выводе 0,1,20, 1, 20,1,2 — несколько способов: 1) Использовать `let` (блочная область для каждой итерации): ```javascript for (let i = 0; i console.log(i), 0); ``` 2) Создать замыкание через IIFE (сохраняем текущее значение в параметре): ```javascript for (var i = 0; i < 3; i++) { (function(j) { setTimeout(() => console.log(j), 0); })(i); } ``` 3) Передать аргумент в `setTimeout` (поддерживается в браузерах и Node): ```javascript for (var i = 0; i < 3; i++) setTimeout(console.log, 0, i); ``` 4) Привязать значение через `bind`: ```javascript for (var i = 0; i < 3; i++) setTimeout(console.log.bind(null, i), 0); ``` 5) Использовать методы массива (создаётся новая переменная `i` в лямбде): ```javascript [0,1,2].forEach(i => setTimeout(() => console.log(i), 0)); ``` Все эти способы приводят к выводу 0,1,20, 1, 20,1,2.
- Переменная `i` объявлена через `var`, она функционально (не блочно) область видимости. Цикл выполняется и создаёт три отложенных колбэка, но все они захватывают одну и ту же `i`. К моменту выполнения таймаутов `i` уже равна 333, поэтому в консоль выводится 3,3,33, 3, 33,3,3.
Как получить в выводе 0,1,20, 1, 20,1,2 — несколько способов:
1) Использовать `let` (блочная область для каждой итерации):
```javascript
for (let i = 0; i console.log(i), 0);
```
2) Создать замыкание через IIFE (сохраняем текущее значение в параметре):
```javascript
for (var i = 0; i < 3; i++) {
(function(j) {
setTimeout(() => console.log(j), 0);
})(i);
}
```
3) Передать аргумент в `setTimeout` (поддерживается в браузерах и Node):
```javascript
for (var i = 0; i < 3; i++) setTimeout(console.log, 0, i);
```
4) Привязать значение через `bind`:
```javascript
for (var i = 0; i < 3; i++) setTimeout(console.log.bind(null, i), 0);
```
5) Использовать методы массива (создаётся новая переменная `i` в лямбде):
```javascript
[0,1,2].forEach(i => setTimeout(() => console.log(i), 0));
```
Все эти способы приводят к выводу 0,1,20, 1, 20,1,2.