什么是时间死区?

IT技术 javascript ecmascript-6 constants let
2021-02-06 01:35:33

我听说在初始化之前访问letconst值可能会导致 aReferenceError因为称为临时死区的东西

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

3个回答

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

  1. 它们是块作用域的
  2. var在声明之前访问 a会得到结果undefined访问 aletconst在它被声明之前抛出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 揭秘ES6 Let、Const 和深度中的“时间死区”(TDZ)

同样有趣的是:为什么会有时间死区
2021-03-22 01:35:33
我认为这是一个很棒的帖子!然而,我的印象是“让”不受提升?我在 Mozilla 文档中发现了这一点:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... 我不是想成为一个脾气暴躁的人,我只是好奇并且愿意澄清。
2021-03-22 01:35:33
@jeows MDN 页面仍然说它们没有被提升。如果您确实确定自己在说什么,则应该尝试对其进行编辑。我想我应该就此发表一个问题。
2021-04-01 01:35:33
@zeroflagL 很好的链接,谢谢。它还说:“foo 不是未声明的,它是未初始化的”,该语言将有助于澄清/纠正上述答案。 let foo在一个块中导致它被提升并在该块的顶部声明。该行let foo导致它被初始化。foo = xyz使其被分配一个值。
2021-04-02 01:35:33
@joews IMO,您可以说它们已被提升,但由于 TDZ 在到达它们的声明之前无法访问它们,或者您可以说它们未被提升但 TDZ 会导致对它们的任何引用引发错误。实际上,这两种说法都同样正确。除了,我认为,您在抽象意义上使用术语“提升”,例如“提升 = 每当引擎意识到该变量的存在时”。这是为什么?另外,规范对此有何评论?
2021-04-06 01:35:33

吊装:
letconstvar都是吊装过程。
(这意味着它们在作用域的顶部进行声明。)

初始化:

  • var也经过初始过程,得到 的初始值undefined
  • while let,const并没有抛出初始进程,所以它们的值仍然无法访问,尽管它们已经声明了。是什么把它们放进去temporal dead zone

所以很快:

吊装过程:var, let,const
初始化过程: var

我想这也是很重要的一提的是let,并const有块范围,var是函数作用域
2021-03-31 01:35:33

在 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;
控制台日志在第二个示例中生成“NaN”(添加undefined的结果5)。所述declaratationvar a被悬挂,inifialisation代码settnga至5不是。
2021-03-12 01:35:33
是的,对,a 没有任何初始化就被提升了。所以 a 将是未定义的。
2021-03-19 01:35:33
引用的第一个示例不正确,请更正或删除它。
2021-04-09 01:35:33