@thefourtheye 说这些变量是正确的无法访问在宣布之前。然而,情况比这要复杂一些。
变量是否声明为let
or 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;
}
This is true both for function and block scopes1.
和...之间的不同var
/function
/function*
声明和let
/const
/class
声明是初始化.
前者初始化为undefined
或在作用域顶部创建绑定时的 (generator) 函数。然而,词法声明的变量仍然存在未初始化的。这意味着一个ReferenceError
当您尝试访问它时会抛出异常。它只会在以下情况下被初始化let
/const
/class
语句被评估,之前(上面)的所有内容被称为颞死区 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz.
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;
将有。
The temporal死区不是一个语法位置,而是time在变量(范围)创建和初始化之间。只要该代码未执行(例如函数体或简单的死代码),在声明上方的代码中引用变量就不是错误,并且如果在初始化之前访问该变量,即使访问代码位于声明下方(例如,在调用太早的提升函数声明中)。
有什么区别吗let
and const
在这件事上?
不,就提升而言,它们的工作原理是相同的。它们之间唯一的区别是const
ant 必须且只能在声明的初始化部分中赋值(const one = 1;
, both const one;
以及后来的重新分配,例如one = 2
均无效)。
1: var
declarations are still working only on the function level, of course