什么是暂时死区?
What is the temporal dead zone?
我听说在初始化之前访问 let
和 const
值可能会导致 ReferenceError
,因为 临时死区.
什么是临时死区,它与作用域和吊装有什么关系,在什么情况下会遇到?
let
和 const
与 var
有两个主要区别:
- 他们是block scoped。
- 在声明之前访问
var
得到结果 undefined
;在声明之前访问 let
或 const
抛出 ReferenceError
:
console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization
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.
}());
来源: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 transpiler. Turn on "high compliance" mode to use it in the REPL 中默认不启用 TDZ。提供 es6.spec.blockScoping
标志以将其与 CLI 一起使用或作为库使用。
推荐阅读:TDZ demystified and ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth.
吊装:
let
,const
,var
都是get hoisted process.
(什么意思是它们向上并在范围的顶部声明。)
初始化:
var
也走初始化过程,得到undefined
的初始值。
- 而
let
,const
并没有抛出初始过程,所以它们的值仍然不可访问,尽管它们已经声明。
什么把它们放在 temporal dead zone
所以很快:
hoisting process: var
, let
, const
Initialisation process:
var
对于 let 和 const 变量,基本上,时间死区是一个区域
"before your variable is declared",
即您无法访问这些变量的值的地方,它会抛出一个错误。
例如
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;
我听说在初始化之前访问 let
和 const
值可能会导致 ReferenceError
,因为 临时死区.
什么是临时死区,它与作用域和吊装有什么关系,在什么情况下会遇到?
let
和 const
与 var
有两个主要区别:
- 他们是block scoped。
- 在声明之前访问
var
得到结果undefined
;在声明之前访问let
或const
抛出ReferenceError
:
console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization
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.
}());
来源: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 transpiler. Turn on "high compliance" mode to use it in the REPL 中默认不启用 TDZ。提供 es6.spec.blockScoping
标志以将其与 CLI 一起使用或作为库使用。
推荐阅读:TDZ demystified and ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth.
吊装:
let
,const
,var
都是get hoisted process.
(什么意思是它们向上并在范围的顶部声明。)
初始化:
var
也走初始化过程,得到undefined
的初始值。- 而
let
,const
并没有抛出初始过程,所以它们的值仍然不可访问,尽管它们已经声明。 什么把它们放在temporal dead zone
所以很快:
hoisting process:
var
,let
,const
Initialisation process:var
对于 let 和 const 变量,基本上,时间死区是一个区域
"before your variable is declared",
即您无法访问这些变量的值的地方,它会抛出一个错误。
例如
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;