什么是暂时死区?

What is the temporal dead zone?

我听说在初始化之前访问 letconst 值可能会导致 ReferenceError,因为 临时死区.

什么是临时死区,它与作用域和吊装有什么关系,在什么情况下会遇到?

letconstvar 有两个主要区别:

  1. 他们是block scoped
  2. 在声明之前访问 var 得到结果 undefined;在声明之前访问 letconst 抛出 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 似乎不是在赋值之前存在。

然而,情况并非如此——letconst 提升(像 varclassfunction),但在进入作用域和被声明为无法访问之间有一段时间。 这段时间是时间死区 (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的初始值。
  • letconst 并没有抛出初始过程,所以它们的值仍然不可访问,尽管它们已经声明。 什么把它们放在 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;