Почему значение переменной var устанавливается после завершения выполнения цикла for?

Почему при использовании ключевого слова "var" в данном примере цикл сначала выполняет свою работу, а затем вызывает колбэк функцию с несуществующим индексом 6? Почему замена "var" на "let" или использование замыкания решает эту проблему? Я прочитал, что это связано с областью видимости, но не понимаю этого полностью. Буду благодарен за объяснение на простом языке.
  • 24 сентября 2023 г. 11:57
Ответы на вопрос 2
Это связано с тем, как работает область видимости и хостинг в JavaScript.

При использовании ключевого слова "var" в JavaScript, переменные объявленные внутри блока (например, цикла for) имеют глобальную область видимости или область видимости функции, а не блока. Это означает, что такая переменная будет доступна и после завершения цикла.

В вашем примере, переменная "var" объявлена внутри цикла for. В каждой итерации цикла она принимает новое значение, но после завершения цикла попытка доступа к этой переменной внутри колбэк функции приводит к тому, что она имеет последнее значение, установленное в цикле (в данном примере - 6).

Однако, при использовании ключевого слова "let" или замыкания, каждая итерация цикла создает новую переменную с ее собственной областью видимости. Это ограничивает область видимости этой переменной только внутри текущей итерации цикла, и каждая итерация цикла имеет свою собственную отдельную переменную "let". В результате, когда колбэк функция вызывается, она использует значение переменной "let" для текущей итерации цикла, что позволяет избежать проблем с последним значением.

Надеюсь, это объяснение понятно и помогает вам разобраться с проблемой!
Читайте дальше о том, что означают область видимости и замыкания. Проще говоря, переменная var является глобальной.

Добавлю еще одно объяснение: 
1. Сначала выполняется весь цикл. Исполнение не заходит внутрь setTimeout - оно откладывается на потом.
2. Наступает "потом". Исполнение входит в первый setTimeout. Здесь проявляется разница:
   - Если используется var-переменная, она не ограничена скобками цикла for. Поэтому в каждой итерации цикла она меняется в глобальной области видимости и в итоге становится равной 6. То есть все setTimeout ищут переменную сначала в своей области видимости (между скобками), не находят ее там и затем видят ее в глобальной области, где она одна и равна 6.
   - Если используется let-переменная, она объявляется локально и сохраняет свое значение в каждой итерации цикла (внутри скобок). Когда setTimeout ищет переменную, каждый находит свое значение локально.
Похожие вопросы