什么是临时性死区
在es6中,代码块内,使用let/const声明之前,该变量都是不可用的,在变量声明之前属于该变量的“死区”、在语法上,称之为“暂时性死区”也叫临时性死区,(temporal dead zone,简称 TDZ)。ES标准并没有明确提出TDZ,但我们常用其描述let、const的不提升效果。
let、const和var的区别
let、const是块级作用域,var是全局作用域
let、const不存在变量提升,在声明前使用会报错:Uncaught ReferenceError,var会进行变量提升,在var声明之前就访问对应的变量,则会得到undefined。
let a = 10;
{
//这里会产生TDZ for a
console.log(a)//报错
let a =20;//a存到了临时性死区中了,对a的声明 这里结束TDZ for a
}
TDZ(临时性死区):流程在进入作用域创建变量,到变量开始可被访问访问之前的一段时间,称为临时性死区
在此例子中,变量a作用域中会先被提升到函数区域的中的最上面,但这时会产生产生TDZ作用的期间,这时候访问a的值,就会跑出ReferenceError错误
关于typeof
我们都知道typeof是用于检测变量的类型,也可判断是否被定义。返回 undefined 表示未定义;但是在 const/let 定义的变量在变量声明之前如果使用了 typeof 就会报错。.
typeof a;//Uncaught ReferenceError: a is not defined
let a;
typeof b;//undefined 不报错
由此可见,如果一个变量根本没有被声明,使用 typeof 反而不会报错。由此可见 not defined 和 undefined 是有区别的。在使用let/const进行声明的变量在使用 typeof 时不一定安全。
默认参数的临时死区
此情况跟let声明类似,定义参数时会为每个参数创建一个新的标识符绑定,该绑定在初始化之前不可被引用,如果试图访问会报错。当调用函数时,会通过传入的值或参数的默认值初始化该参数。
function add(a, b = a) {
return a + b;
}
console.log(add(2));//4
其实在此情况下,调用函数add(2)时js引擎做了以下操作:
let a = 2;
let b =a;
在传参时,已经对a做了初始化,所以b可以访问a的值。但反过来a访问b时会报错
```javascript
let b=2;
function add(a=b, b) {
return a + b;
}
console.log(add(undefined,1));//Uncaught ReferenceError: y is not defined
调用add(undefined,1)时,相当于
//add(undefined,1)
let a=b;
let b=1;
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。虽然在函数外部定义了变量y,但参数形成的是一个单独的作用域,初始化结束时才会这个作用域才会消失。所以在x初始化时,y并未被初始化,此时y尚处于临时性死区中。
`