1. 变量提升
在日常开发中,我们应该会碰到如下这种情况:
console.log(a) // undefined
var a = 1;
上面代码中,a还没被声明前被调用,却可以输出undefined,而不是报错,这里其实就是变量被提升了;实际上,上面等价于:
var a
console.log(a)
a = 1
这里为何变量会被提升呢,那是因为JS代码片段执行之前都会被预编译,预编译过程非常短暂,在预编译过程中,JS会搜集所有变量提前声明,等到具体执行的时候才会去执行某个代码片段,这就是变量提升的本质
既然var声明的变量会提升,那么const和let声明的变量会被提升吗?
console.log(a) // 报错
let a = 1;
console.log(b) // 报错
const b = 1;
上面这段代码里面,用let/const声明的变量在声明之前输出会报错,这里是因为let和const是块级作用域,并且块级作用域存在暂时性死区,那么什么是暂时性死区呢?
2. 暂时性死区
暂时性死区其实就是当我们进入一个作用域中,let、const声明的变量其实已经存在了,但是不允许被获取,只有代码执行到声明处才可以被获取
{
let a = 1;
}
console.log(a) // 报错
{
const b = 1;
}
console.log(b) // 报错
以上例子会报错,主要是因为用let、const是块级作用域,定义的变量存在暂时性死区,并且在作用域外部是无法访问内部定义的变量的,所以会报错;let和const定义的变量无法被提升,let/const一旦声明变量,这个变量就已经被绑定到当前作用域中,只有代码执行到这块才可以被执行调用
console.log(a)
var a = 1;
function func() {
console.log(a)
var a = 2;
console.log(a)
}
func()
console.log(a)
// 输出结果:undefined undefined 2 1
这里变量a会被提升,a不受作用域控制,会被提升
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量