我听说在初始化之前访问let
和const
值可能会导致ReferenceError
因为暂时死区。< / p>
什么是暂时死区,它与范围和吊装有何关系,以及在什么情况下遇到?
答案 0 :(得分:168)
let
和const
与var
有两大不同:
var
的结果为undefined
;在宣布let
之前访问const
或ReferenceError
{/ 1}}:
console.log(aVar); // undefined
console.log(aLet); // causes ReferenceError: aLet is not defined
var aVar = 1;
let aLet = 2;
从这些示例中可以看出,let
声明(和const
,其工作方式相同)可能不是hoisted,因为aLet
似乎不存在它被分配了一个值。
但事实并非如此 - let
和const
已悬挂(例如var
,class
和function
),但在进入范围和被宣布无法访问范围之间有一段时间。 这段时间是暂时死区(TDZ)。
当aLet
宣布而不是分配时,TDZ结束:
//console.log(aLet) // would throw ReferenceError
let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10
此示例显示let
已悬挂:
let x = 'outer value';
(function() {
// start TDZ for x
console.log(x);
let x = 'inner value'; // declaration ends TDZ for x
}());
Credit: Temporal Dead Zone (TDZ) demystified
访问内部范围中的x
仍会导致ReferenceError
。如果未提升let
,则会记录outer value
。
TDZ是一件好事,因为它有助于突出显示错误 - 在声明之前访问一个值很少是故意的。
TDZ也适用于默认函数参数。参数从左到右进行评估,每个参数都在TDZ中,直到它被分配:
// b is in TDZ until its value is assigned
function testDefaults(a=b, b) { }
testDefaults(undefined, 1); // throws ReferenceError because the evaluation of a reads b before it has been evaluated.
默认情况下,babel.js转换器中未启用TDZ。启用“高符合性”模式以在REPL中使用它。提供es6.spec.blockScoping
标志以将其与CLI一起使用或作为库使用。
建议进一步阅读:TDZ demystified和ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth。
答案 1 :(得分:1)
吊装:
let
,const
,var
都被提升了。
(这意味着它们会上升并在范围的顶部声明。)
初始化:
var
还会引发初始过程,并获得undefined
的初始值。let
和const
并没有抛出初始过程,因此尽管它们已经声明,但它们的值仍然不可访问。
它们放在temporal dead zone
所以不久之后:
吊装过程:
var
,let
,const
初始化过程:var
答案 2 :(得分:-1)
对于let和const变量,基本上,时间死区是一个区域
“在声明变量之前”,
即无法访问这些变量的值,则会引发错误。
例如。
let sum = a + 5; //---------
//some other code // | ------> this is TDZ for variable a
// |
console.log(sum) //---------
let a = 5;
上面的代码给出了错误
当我们将var用作变量'a'时,相同的代码不会给出错误
例如。
var sum = a;
console.log(sum) //prints undefined
var a = 5;