我听说在初始化之前访问let
和const
值可能会导致 aReferenceError
因为称为临时死区的东西。
什么是时间死区,它与范围和吊装有什么关系,它在什么情况下遇到?
我听说在初始化之前访问let
和const
值可能会导致 aReferenceError
因为称为临时死区的东西。
什么是时间死区,它与范围和吊装有什么关系,它在什么情况下遇到?
let
并且与const
有两个广泛的区别var
:
var
在声明之前访问 a会得到结果undefined
;访问 alet
或const
在它被声明之前抛出ReferenceError
:console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization
var aVar = 1;
let aLet = 2;
从这些示例中可以看出,let
声明(和const
,其工作方式相同)可能不会被提升,因为aLet
在为其分配值之前似乎不存在。
然而,情况并非如此——let
并且const
被提升(如var
、class
和function
),但在进入范围和被声明为无法访问它们之间有一段时间。这个时期是时间死区(TDZ)。
TDZ 在aLet
被声明而不是被分配时结束:
// 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.
}());
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 揭秘和ES6 Let、Const 和深度中的“时间死区”(TDZ)。
吊装:
let
、const
、var
都是吊装过程。
(这意味着它们在作用域的顶部进行声明。)
初始化:
var
也经过初始过程,得到 的初始值undefined
。let
,const
并没有抛出初始进程,所以它们的值仍然无法访问,尽管它们已经声明了。是什么把它们放进去temporal dead zone
所以很快:
吊装过程:
var
,let
,const
初始化过程:var
在 let 和 const 变量的情况下,基本上,临时死区是一个区域
“在声明变量之前”,
即在你不能访问这些变量的值的地方,它会抛出一个错误。
前任。
let sum = a + 5; //---------
//some other code // | ------> this is TDZ for variable a
// |
console.log(sum) //---------
let a = 5;
上面的代码给出了一个错误
当我们对变量“a”使用 var 时,相同的代码不会出错,
前任。
var sum = a;
console.log(sum) //prints undefined
var a = 5;