Вот такой код:
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, в этом примере.
Спасибо!