Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 31.01.2021, 21:28
Аспирант
Отправить личное сообщение для denis_alekss Посмотреть профиль Найти все сообщения от denis_alekss
 
Регистрация: 01.12.2020
Сообщений: 55

НЕ срабатывает цикл for
Почему код срабатывает только тогда когда
Код:
var i = 0;
поменять на
Код:
let i = 0;
?
Если оставить код как есть вывод:

Код:
fib[6] = undefined
Сам код:

Код:
<!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>
Вот такой код:

Код:
<!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[${i}] = ${fib[i]}`)
	},1500)
	})(i)
}

    </script>
</body>
</html>
выдаст также
Код:
fib[6] = undefined

Последний раз редактировалось denis_alekss, 31.01.2021 в 21:56.
Ответить с цитированием
  #2 (permalink)  
Старый 31.01.2021, 21:38
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,121

denis_alekss,
https://javascript.ru/basic/closure#...-ispolzovaniya
Ответить с цитированием
  #3 (permalink)  
Старый 31.01.2021, 21:43
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Переменные, объявленные var попадают в глобальный объект или имеют область видимости функции.
Т.е в вашем случае (когда var) будет всего одна глобальная переменная (содержащаяся в глобальном объекте window)
Переменные объявленные let имеют глобальную область видимости (это не тоже самое, что глобальный объект) или область видимости блока. Блок это все, что в {} тело функции или цикл - частный случай блока. Обнако у циклов блок начинается не с {, а с оператора for (или while)
Фактически на каждой итерации цикла for заводится своя переменная i.
Далее, когда вы создаете функцию
function() {
console.log(`fib[${i}] = ${fib[i]}`)
}
Она использует замыкание на переменную i, созданную именно на этой итерации.
Ответить с цитированием
  #4 (permalink)  
Старый 31.01.2021, 21:49
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,121

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)
}
Ответить с цитированием
  #5 (permalink)  
Старый 31.01.2021, 21:58
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,750

Сообщение от denis_alekss
Вот такой код:

Код:
<!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[${i}] = ${fib[i]}`)
},1500)
})(i)
}

</script>
</body>
</html>
выдаст также
Код:
fib[6] = undefined
А надо
<!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>
Ответить с цитированием
  #6 (permalink)  
Старый 31.01.2021, 22:09
Аспирант
Отправить личное сообщение для denis_alekss Посмотреть профиль Найти все сообщения от denis_alekss
 
Регистрация: 01.12.2020
Сообщений: 55

Цитата:
let создаёт замыкание типа такого ...
А var не создает замыкания, из-за этого вывод через полтора секунды
fib[6] = undefined


?
Ответить с цитированием
  #7 (permalink)  
Старый 31.01.2021, 22:20
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,121

denis_alekss,
i на момент срабатывая любого setTimeout имеет значение 6 -- элемента с таким индексом не существует.
Ответить с цитированием
  #8 (permalink)  
Старый 31.01.2021, 22:32
Аспирант
Отправить личное сообщение для denis_alekss Посмотреть профиль Найти все сообщения от denis_alekss
 
Регистрация: 01.12.2020
Сообщений: 55

Если код оставить как есть
<!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 само по себе в движке создает замыкание?
Ответить с цитированием
  #9 (permalink)  
Старый 31.01.2021, 22:36
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,121

Сообщение от denis_alekss
let само по себе в движке создает замыкание?
да
Ответить с цитированием
  #10 (permalink)  
Старый 31.01.2021, 22:42
Аспирант
Отправить личное сообщение для denis_alekss Посмотреть профиль Найти все сообщения от denis_alekss
 
Регистрация: 01.12.2020
Сообщений: 55

По какой причине 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>

Последний раз редактировалось denis_alekss, 31.01.2021 в 23:10.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Таймер срабатывает раньше времени или вообще не срабатывает Terebonko Элементы интерфейса 6 03.08.2017 12:43
Не срабатывает последний цикл arkadii_parovozov Общие вопросы Javascript 7 01.12.2016 16:36
Как подчинить себе цикл wreder jQuery 16 20.11.2013 22:17
Цикл завешивает страницу, помогите Romingood jQuery 5 19.10.2013 14:30
AJAX запрос в Internet Explorer срабатывает через раз nikolayseo jQuery 5 13.11.2012 00:13