@olegivanchenko80

Контекст выполнения в js: запутался, как понять?

Есть пример:

for (var count = 0; count < 50 ; count ++) {
  setTimeout(function() {
    console.log(count);
  }, 0);
}


Никак не пойму, почему вывод консоли так отличается?
Догадки есть, но хотелось бы именно понятный полный ответ получить)
  • Вопрос задан
  • 731 просмотр
Решения вопроса 1
IonDen
@IonDen
JavaScript developer. IonDen.com
Тут дело не в контексте, а в том что вы смешиваете синхронный код (цикл for) и асинхронный setTimeout (даже если вы поставите 0 секунд, это не сделает его синхронным, это всего лишь значит что будет использовано минимально возможное время, близкое к 0).

Именно по этому вначале цикл выполнится 50 раз, и переменная count будет равной 50. И тоолько потом, через какое-то минимльное время, запустится 50 таймаутов и конечно каждый из них выведет 50 в консоль.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
А так ?
for (let count = 0; count < 50 ; count ++) {
  setTimeout(function() {
    console.log(count);
  }, 0);
}

https://learn.javascript.ru/functions-closures
https://learn.javascript.ru/let-const

Дело именно в контексте и области видимости.
Функция, которая вызывается внутри setTimeout берет переменную count из замыкания, так как переменные объявленные через var всплывают, то все функции фактически будут обращаться к одной переменной, значение которой уже равно 50.

Область видимости переменной let – блок {...} тоесть каждая итерация будет брать из замыкания свою переменную.

Пожалуйста почитайте про ES6 и ES7 и используйте новые возможности JS let, const, Promise, классы, генераторы и итераторы это позволит вам писать более чистый и понятный код. Если вдруг попадете в Проект, который будет требовать поддержку IE10, вы всегда можете прогнать код через babel или использовать полифилы, а вообще избегайте таких проектов. На рынке сейчас на Фронтов спрос, и всегда можно выбрать проект поинтереснее.
Ответ написан
Комментировать
lazalu68
@lazalu68
Salmon
Порядок действий такой:

1. Выполнить цикл (в котором много раз ставится в очередь задач функция "function() { console.log(count); }"),
2. Выполнить следующие задачи из очереди, то есть 50 раз выполнить функцию "function() { console.log(count); }", во время выполнения которой переменная count равна 50.
Ответ написан
Комментировать
Если хочешь сделать сделать типа "цикл" с интервалами:
var count=0;
var b=setInterval(function(){
console.log(count);
if(count==50){
    clearInterval(b);
}
count++;
},50);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы