@thefourtheye правильно говорит, что эти переменные не могут быть доступны до их объявления. Тем не менее, это немного сложнее, чем это.
Переменные объявлены с let
или const
нет? Что на самом деле здесь происходит?
Все декларации ( var
, let
, const
, function
, function*
, class
) являются "взвалили" в JavaScript. Это означает, что если имя объявляется в области, в этой области идентификатор всегда будет ссылаться на эту конкретную переменную:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Это верно как для функциональных, так и для блочных областей 1 .
Разница между var
/ function
/ function*
декларациями и let
/ const
/ class
декларациями заключается в инициализации .
Первые инициализируются с помощью функции undefined
или (генератора) справа, когда привязка создается в верхней части области. Однако лексически объявленные переменные остаются неинициализированными . Это означает, что возникает ReferenceError
исключение при попытке доступа к нему. Он будет инициализирован только после вычисления оператора let
/ const
/ class
, все до (выше), которое называется временной мертвой зоной .
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Обратите внимание, что let y;
оператор инициализирует переменную с помощью undefined
like let y = undefined;
.
Временная мертвая зона не является синтаксическим расположение, а , скорее, время между переменным (масштабом) созданием и инициализацией. Ссылка на переменную в коде над объявлением не является ошибкой, если этот код не выполняется (например, тело функции или просто мертвый код), и будет выдано исключение, если вы получите доступ к переменной до инициализации, даже если доступ код находится ниже объявления (например, в объявлении поднятой функции, которое вызывается слишком рано).
Есть ли разница между let
и const
в этом вопросе?
Нет, они работают так же, как считается подъем. Единственная разница между ними заключается в том, что const
муравей должен быть и может быть назначен только в части инициализации объявления ( как недопустимые переназначения const one = 1;
, так const one;
и последующие, например one = 2
).
1: var
объявления все еще работают только на уровне функций, конечно
let foo = () => bar; let bar = 'bar'; foo();
иллюстрирует, что все декларации являются эффектом подъема еще лучше, потому что это не очевидно из-за временной мертвой зоны.