小编典典

什么是时间死区?

all

我听说在初始化之前访问let和值可能会因为所谓的 时间死区* 而导致。const``ReferenceError *

什么是时间死区,它与范围和提升有什么关系,在什么情况下会遇到?


阅读 87

收藏
2022-07-29

共1个答案

小编典典

let并与const有两个广泛的区别var

  1. 它们是块作用域的。
  2. var在声明之前访问 a有结果undefined;访问 a letorconst在它被声明之前抛出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
提升(如varclassfunction),但是在进入范围和被声明之间有一段时间无法访问它们。 这个时期是时间死区(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.
}());

信用:时间死区(TDZ)揭秘

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
和深度中的“时间死区”(TDZ)

2022-07-29