什么是颞时盲区?

2022-08-30 01:40:05

我听说在初始化之前访问和值可能会导致一个,因为一种叫做时间盲区的东西。letconstReferenceError

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


答案 1

let并且与以下两种有很大的区别:constvar

  1. 它们是块范围的
  2. 在声明之前访问 a 具有结果 ;访问 a 或在声明它之前抛出:varundefinedletconstReferenceError

console.log(aVar); // undefined
console.log(aLet); // Causes ReferenceError: Cannot access 'aLet' before initialization

var aVar = 1;
let aLet = 2;

从这些示例中可以看出,声明(和 的工作方式相同)可能不会被吊起,因为在为其赋值之前似乎不存在声明。letconstaLet

然而,事实并非如此 , 并且吊起(如 和 ),但是在进入范围和声明之间有一段时间无法访问它们。这个时期是时间盲区(TDZ)。letconstvarclassfunction

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.
}());

图片来源:Temporal Dead Zone (TDZ) 揭秘

在内部作用域中进行访问仍会导致 .如果没有吊装,它将记录.xReferenceErrorletouter value

TDZ 是一件好事,因为它有助于突出显示 Bug — 在声明值之前访问该值很少是有意为之。

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 中使用它。提供该标志以将其与 CLI 一起使用或用作库。es6.spec.blockScoping

推荐进一步阅读:TDZ揭秘ES6 Let,Const和“Temporal Dead Zone”(TDZ)深度


答案 2

吊装:
,,都是吊装过程。
(这意味着它们位于上层,并在范围的顶部声明。letconstvar

初始化:

  • var还要完成初始过程,并获取 的初始值。undefined
  • 而 ,没有抛出初始过程,因此尽管它们已经声明,但它们的值仍然无法访问。什么把他们放进去letconsttemporal dead zone

所以在很短的时间内:

提升过程: , ,
初始化过程:varletconstvar