@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;оператор инициализирует переменную с помощью undefinedlike let y = undefined;.
Временная мертвая зона не является синтаксическим расположение, а , скорее, время между переменным (масштабом) созданием и инициализацией. Ссылка на переменную в коде над объявлением не является ошибкой, если этот код не выполняется (например, тело функции или просто мертвый код), и будет выдано исключение, если вы получите доступ к переменной до инициализации, даже если доступ код находится ниже объявления (например, в объявлении поднятой функции, которое вызывается слишком рано).
Есть ли разница между letи constв этом вопросе?
Нет, они работают так же, как считается подъем. Единственная разница между ними заключается в том, что constмуравей должен быть и может быть назначен только в части инициализации объявления ( как недопустимые переназначения const one = 1;, так const one;и последующие, например one = 2).
1: varобъявления все еще работают только на уровне функций, конечно
let foo = () => bar; let bar = 'bar'; foo();иллюстрирует, что все декларации являются эффектом подъема еще лучше, потому что это не очевидно из-за временной мертвой зоны.