JavaScript:let命令 暂时性死区

Vesta ·
更新时间:2024-09-20
· 992 次阅读

要点:let 命令的暂时性死区 时间:2020-01-09 一、在块级作用域内若存在let命令,则所声明的变量就“绑定”(binding)这个区域,不受外部的影响。

(1)如果区块中存在let命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。也就是说,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
如下:存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

var tmp = 123; if (true) { tmp = 456; // ReferenceError: Cannot access 'tmp' before initialization let tmp; }

(2)在let命令声明某变量之前,都属于该变量的死区范围。
如下:在let命令声明变量tmp之前,都属于其死区范围。

if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError 引用错误, 声明之前就使用 tmp console.log(tmp); // ReferenceError 同上 let tmp; // TDZ 结束 console.log(tmp); // undefined 未赋值但已声明 值为undefined tmp = 777; console.log(tmp); // 777 } 二、暂时性死区 对 typeof 的影响

(1)“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。
例如:变量val使用let命令声明,所以在声明之前,都属于val的“死区范围”,只要用到该变量就会报错。因此typeof运行时就会抛出一个ReferenceError

typeof val; // ReferenceError: Cannot access 'val' before initialization let val;

(2)如果一个变量根本没有被声明,使用typeof反而不会报错。

typeof item // "undefined" 未声明 item

(3)综上两点所述:在没有let声明之前,typeof运算符是百分之百安全的,永远不会报错。但是一旦使用let声明,则typeof不再是一个百分之百安全的操作。这样的设计是为了养成良好的编程习惯,变量一定要在声明之后使用,否则就报错。

三、隐蔽型 TDZ

(1)隐蔽型死区即指非直观可知的变量死区范围
如下:调用fn函数之所以报错,是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于“死区”。而调用fo函数y的默认值是x,就不会报错,因为此时x已经声明了。

function fn(x = y, y = 1) { return [x, y]; } fn(); // ReferenceError: Cannot access 'y' before initialization function fo(x = 1, y = x) { return [x, y]; } fo(); // [1, 1]

(2)与var的行为不同。使用let声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量x的声明语句还没有执行完成前,就去取x的值,导致报错x 未定义“。ES6 规定暂时性死区和let语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

var x = x; // 不报错 let x = x; // ReferenceError: x is not defined 四、TDZ 总结

综上所述:暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。


作者:codingScript



let JavaScript

需要 登录 后方可回复, 如果你还没有账号请 注册新账号