什么是暂时死区?

joe*_*ews 128 javascript const let ecmascript-6

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

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

joe*_*ews 180

let并且const有两个不同的区别var:

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

console.log(aVar); // undefined
console.log(aLet); // causes ReferenceError: aLet is not defined
var aVar = 1;
let aLet = 2;
Run Code Online (Sandbox Code Playgroud)

从这些示例中可以看出,let声明(以及const以相同的方式工作)可能不会被提升,因为aLet在为其分配值之前似乎不存在声明.

但事实并非如此 - let并且const 提升(如var,classfunction),但是在进入范围和被宣布无法访问范围之间存在一段时间.这个时期是时间死区(TDZ).

该TDZ结束时aLet宣布,而不是分配:

//console.log(aLet)  // would throw ReferenceError

let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10
Run Code Online (Sandbox Code Playgroud)

此示例显示let已挂起:

let x = 'outer value';
(function() {
  // start TDZ for x
  console.log(x);
  let x = 'inner value'; // declaration ends TDZ for x
}());
Run Code Online (Sandbox Code Playgroud)

信用:时间死区(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.
Run Code Online (Sandbox Code Playgroud)

babel.js转换器默认不启用TDZ .打开"高符合性"模式以在REPL中使用它.提供es6.spec.blockScoping标志以将其与CLI一起使用或作为库使用.

推荐进一步阅读:TDZ神秘化,ES6 Let,Const和"时间死区"(TDZ)深度.

  • 同样有趣:[为什么会出现暂时死区](http://www.2ality.com/2015/10/why-tdz.html) (3认同)
  • 我认为这是一个很棒的帖子!但是,我给人的印象是“让”没有被吊起吗?我在Mozilla文档中发现了这一点:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let我并不是想成为一个curmudgeon,我只是好奇而已公开澄清。 (2认同)
  • @jeows MDN 页面仍然说它们没有被提升。如果您确实确定自己在说什么,则应该尝试对其进行编辑。我想我应该就此发表一个问题。 (2认同)

ofi*_*hai 13

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

初始化:

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

所以很快:

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


nir*_*ale 6

在 let 和 const 变量的情况下,基本上,临时死区是一个区域

“在声明变量之前”,

即在您无法访问这些变量的值的地方,它会抛出错误。

前任。

let sum = a + 5;        //---------
//some other code       //         | ------>  this is TDZ for variable a
                        //         |
console.log(sum)        //---------
let a = 5;
Run Code Online (Sandbox Code Playgroud)

上面的代码给出了一个错误

当我们对变量“a”使用 var 时,相同的代码不会给出错误,

前任。

var sum = a;                            
console.log(sum)     //prints undefined
var a = 5;
Run Code Online (Sandbox Code Playgroud)