НЕ срабатывает цикл for
Почему код срабатывает только тогда когда
Код:
var i = 0; Код:
let i = 0; Если оставить код как есть вывод: Код:
fib[6] = undefined Код:
<!DOCTYPE html> Код:
<!DOCTYPE html> Код:
fib[6] = undefined |
denis_alekss,
https://javascript.ru/basic/closure#...-ispolzovaniya |
Переменные, объявленные var попадают в глобальный объект или имеют область видимости функции.
Т.е в вашем случае (когда var) будет всего одна глобальная переменная (содержащаяся в глобальном объекте window) Переменные объявленные let имеют глобальную область видимости (это не тоже самое, что глобальный объект) или область видимости блока. Блок это все, что в {} тело функции или цикл - частный случай блока. Обнако у циклов блок начинается не с {, а с оператора for (или while) Фактически на каждой итерации цикла for заводится своя переменная i. Далее, когда вы создаете функцию function() { console.log(`fib[${i}] = ${fib[i]}`) } Она использует замыкание на переменную i, созданную именно на этой итерации. |
denis_alekss,
let создаёт замыкание типа такого ... const fib = [1, 2, 3, 5, 8, 13]; for (var i = 0; i < fib.length; i++) { setTimeout(( function(i) { return function() { console.log(`fib[${i}] = ${fib[i]}`) } } )(i), 1500 * i) } |
Цитата:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> const fib = [1,2,3,5,8,13] for(var i = 0; i < fib.length; i++){ (function(j){ setTimeout(function() { console.log(`fib[${j}] = ${fib[j]}`) },1500) })(i) } </script> </body> </html> |
Цитата:
fib[6] = undefined ? |
denis_alekss,
i на момент срабатывая любого setTimeout имеет значение 6 -- элемента с таким индексом не существует. |
Если код оставить как есть
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> const fib = [1,2,3,5,8,13] for(var i = 0; i < fib.length; i++){ setTimeout(function() { console.log(`fib[${i}] = ${fib[i]}`) },1500) } </script> </body> </html> и поменять просто на let не используя замыкания, код выведет правильно из-за того что let само по себе в движке создает замыкание? |
Цитата:
|
По какой причине var не создает замыкания и не сохраняет i за каждой итерацией?
Вот здесь будет 3 раза подряд 5 выводится, хотя я вывожу разные индексы <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script> let result = [] for (var i = 0; i < 5; i++){ result.push(function(){ console.log(i) }) } result[2]() result[4]() result[1]() </script> </body> </html> |
|
Цитата:
let просто создает переменную в своей области видимости. А замыкание это все таки не создание переменной, а ссылка на переменную из другой области видимости. Просто let i никакого замыкания не создаст. А вот когда мы в другой области видимости создадим на нее ссылку, то это будет уже замыкание. Сборщик мусора не уничтожит эту переменную let fun; { let i = 0, j = 1; // нет тут замыкания fun = ()=> console.log(i); // а вот это уже замыкание } Мы в области видимости функции создали ссылку на переменную i из области действия блока. Блок отработал, переменная j исчезла. А i осталась. И будет существовать, пока жива функция. Замыкания и с var успешно делаются var fun; (function () { var i = 0, j = 1; // нет тут замыкания fun = function () { console.log(i)}; // а вот это уже замыкание })() Цитата:
Переменные объявленные var имеют области видимости глобального объекта или функции, но не блока. Переменная объявленная через vаr внутри блока поднимается наверх в функцию или в глобальный объект. function foo (a) { for (var i=0; i<a.length; i++) {...} ..... for (var i=0; i<a.length; i++) {...} } эквивалентно function foo (a) { var i // будет только одна переменная for (i=0; i<a.length; i++) {...} ..... for (i=0; i<a.length; i++) {...} } |
Часовой пояс GMT +3, время: 01:47. |