0

Коллеги, я тут в трех соснах запутался :)

function abc() { 
  a = 2; 
  console.log('func a ',a);
}
let a = 3;
abc(); 
console.log("let a ->",a);

Вот такой код генерирует следующий вывод

func a  2
let a -> 2

Я ожидал что этот код выдаст в конце

let a -> 3

Собственно вопрос про лексическое окружение функции. Когда функция abc создается - она условно поднимается наверх и в ее лексическом окружении ссылка на внешнее окружение ведет на abc и как показала практика туда же попадает переменная a.

Не могу понять почему так происходит ?

Для let переменных существует "dead zone" - когда обращение к ним до момента объявления выдает refrence error, т.е. let переменные не "поднимаются" вверх

В моем понимании при объявлении function abc let переменная a находится в "dead zone", но при этом как то попадает в лексическое окружение функции abc

У меня как то эти два момента никак не связываются между собой.

Можете объяснить ?

  • dead zone - это не место в коде. это момент между инициализацией и использованием. Поменяй местами строки let a = 3; abc(); чтобы стало abc(); let a = 3; и увидишь ожидаемую ошибку – Grundy Sep 11 '22 at 05:45

1 Answers1

0

Собственно в вопросе выше я перепутал понятия hosting: https://developer.mozilla.org/ru/docs/Glossary/Hoisting

и dead zone: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/let

MDN пишет: "В стандарте ECMAScript 2015 переменные, объявленные директивой let, переносятся в начало блока."

Поскольку у нас функция внутри модуля, то все декларации let, объявленные внутри модуля поднимаются наверх модуля и тогда любая функция внутри модуля при вызове при формировании контекста вызова получает ссылку на внешнее лексическое окружение в котором, в частности содержатся все функции, объявленные в теле модуля, все переменные let, объявленные внутри модуля.

https://developer.mozilla.org/en-US/docs/Glossary/Scope

Поэтому переменная let хоть и объявлена ниже объявления функции, но все равно она попадает в контекст модуля, а при вызове функции в лексическое окружение функции передается ссылка на контекст модуля в котором переменная a уже объявлена.