Область видимости 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 и уходим в бесконечный цикл.:dance: Всё это прекрасно, но с let подобного не происходит.:no: Почему? Проверка alert после завершения bar, говорит нам о том, что то, что происходит внутри bar не влияет, на значение i в цикле. Почему? Вот эта строчка внутри bar: i = 3 - не объявляет новую переменную. А значит она должна идти вовне, находить там текущий i = 0, и присваивать ему значение 3. Но она почему-то этого не делает. Почему?:stop: А делает она следующее: каким-то образом "проскальзывает" мимо объявленного i в цикле, топает в глобальную область видимости, и объявляет глобальную переменную i, и, в дальнейшем, bar уже взаимодействует с этой переменной, в глобальной области видимости. Если мы, после завершения работы foo, выведем alert(i), ничего не объявляя, то программа выведет 3, значение из функции bar. Кстати, если функции bar не будет, а все эти операции делать внутри цикла, то поведение будет, аналогичное var. Объясните, пожалуйста, логику работы let, в этом примере.:) Спасибо! |
Эту статью читали?
https://learn.javascript.ru/let-const |
Как сказать-то... Из серии, "а слона-то я и не заметил" :)
Тут же функция bar лежит в корне функции foo, а вызывается не из корня, а из блока for, вот bar ищет сначала внутри себя, затем в корне функции foo(в цикл for не заходит (а в случае var переменная поднялась бы в корень функции foo) ), а затем идёт в глобальную зону видимости. Ну а далее как я описал в предыдущем сообщении. Сорри. |
Часовой пояс GMT +3, время: 01:18. |