Когда блок впервые обнаружен (с {
), создается новый контекст выполнения , который создает новую пустую Лексическую среду (которая в основном является отображением контейнера) имена переменных в текущей непосредственной области видимости их значений). Затем механизм перебирает , и все переменные, объявленные с const
или let
в непосредственном блоке, инициализируются. (Но, несмотря на инициализацию, они не будут ссылаться до тех пор, пока движок не встретит линию const <variableName>
или let <variableName>
- TDZ)
Итак, простые блоки do не создают новая область видимости, которая будет заполнена, если какие-либо операторы непосредственно внутри этого блока объявят переменную с const
или let
.
. Вы можете увидеть это в действии с помощью отладчика:
/* Hoisting took place in {}. */
{
debugger;
let a=100;
console.log(a); // 100
}
console.log(a); // ReferenceError: a is not defined
Результат в Chrome devtools:
(хотя это немного вводит в заблуждение - a
на самом деле не содержит undefined
, он не был полностью создан в этот момент)
Имена переменных const
и let
подняты в том смысле, что интерпретатор распознает с начала блока, что ссылаться на них будет недопустимо, пока они не будут полностью созданы через линию const
или let
.
Это не просто блоки - любой Уровень кода приведет к тому же типу событий (например, на верхнем уровне, или внутри блока for
, или внутри функции).