Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 18.06.2020, 17:00
Интересующийся
Отправить личное сообщение для Launder Посмотреть профиль Найти все сообщения от Launder
 
Регистрация: 25.04.2019
Сообщений: 19

Область видимости let и var. Что меняет внутренняя функция?
Вот такой код:
function foo() 
   {
       function bar(a)
             {
		    i = 3;
		    alert( a + i );
	     }

       for (let i=0; i<7; i++) 
             {
		    bar( i * 2 );
                    alert(`i = ${i}`); // смотрим меняет ли i функция
	     }
   }
foo();

Если поменять в for, let на var, то логика работы программы будет понятна:
1. функция foo создала функцию bar и запустила цикл for.
2. i = 0, запускается bar, a = i*2 = 0.
3. на первом же шаге исполнения, происходит операция i = 3. Поскольку переменная внутри функции не объявлена, то она идёт вверх, к месту своего создания (функция foo), и ищет переменную внутри неё, находит, присваивает ей 3.
3. считает 0 + 3, выводит 3.
4. bar заканчивает свою работу, следующий alert - служебный, чтоб проконтролировать текущее значение переменной, он, естественно выдаёт 3, и после окончания цикла (или вначале следующего?) происходит инкремирование i, и он становится равным 4.
5. первая операция a = i*2 (в скобках bar) даёт нам а = 8.
6. дальше i принудительно снова становится равным трём соответственно выводится 8 + 3 = 11.
7. убеждаемся что i у нас по прежнему равно трём, заканчиваем, инкримируем i, снова получаем 4 и уходим в бесконечный цикл.

Всё это прекрасно, но с let подобного не происходит. Почему?
Проверка alert после завершения bar, говорит нам о том, что то, что происходит внутри bar не влияет, на значение i в цикле. Почему?
Вот эта строчка внутри bar: i = 3 - не объявляет новую переменную. А значит она должна идти вовне, находить там текущий i = 0, и присваивать ему значение 3. Но она почему-то этого не делает. Почему? А делает она следующее: каким-то образом "проскальзывает" мимо объявленного i в цикле, топает в глобальную область видимости, и объявляет глобальную переменную i, и, в дальнейшем, bar уже взаимодействует с этой переменной, в глобальной области видимости. Если мы, после завершения работы foo, выведем alert(i), ничего не объявляя, то программа выведет 3, значение из функции bar.
Кстати, если функции bar не будет, а все эти операции делать внутри цикла, то поведение будет, аналогичное var.
Объясните, пожалуйста, логику работы let, в этом примере.
Спасибо!

Последний раз редактировалось Launder, 20.06.2020 в 22:32.
Ответить с цитированием
  #2 (permalink)  
Старый 18.06.2020, 17:52
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

Эту статью читали?
https://learn.javascript.ru/let-const
Ответить с цитированием
  #3 (permalink)  
Старый 20.06.2020, 22:44
Интересующийся
Отправить личное сообщение для Launder Посмотреть профиль Найти все сообщения от Launder
 
Регистрация: 25.04.2019
Сообщений: 19

Как сказать-то... Из серии, "а слона-то я и не заметил"
Тут же функция bar лежит в корне функции foo, а вызывается не из корня, а из блока for, вот bar ищет сначала внутри себя, затем в корне функции foo(в цикл for не заходит (а в случае var переменная поднялась бы в корень функции foo) ), а затем идёт в глобальную зону видимости. Ну а далее как я описал в предыдущем сообщении.
Сорри.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помощь с асинхронностю serfer89 Node.JS 1 30.01.2018 09:34
Как правильно перебрать условия из разных таблиц? the_little Общие вопросы Javascript 10 30.10.2017 09:19
Заменить значения value в форме при отправке на email the_little Общие вопросы Javascript 26 29.10.2017 21:26
Помогите пож с JSON, передача id ссылки. wisma jQuery 22 10.02.2014 15:36
CComponent - кроссбраузерные компоненты tenshi Ваши сайты и скрипты 5 20.04.2010 23:22