let声明的变量到底有没有变量提升?
我们都知道var声明的变量,会存在变量提升,就是在变量声明之前,就可以被访问。
代码如下
(function(){
console.log(x) //undefind
var x = "1111"
}())
这里的x打印出来的是undefind,就是因为变量提升,这个大家都知道没问题
我们在来看一段代码
var x = y = "global"
(function(){
console.log(x) //global
console.log(y) //global
}())
我们用var声明了变量x y 为global,在自执行函数里面,我们打印x和y,都显示global,没有问题
再看
var x = y = "global"
(function(){
console.log(x)//undifind
console.log(y)//报错 下图可见
var x = "1111"
let y = "1111"
}())
这里同样声明了x y为global ,在自执行函数里面打印x和y,只不过后面又多了两行代码,这里打印x结果为undifind,打印y会报错,x打印出undifind是因为我们在之后又定义了var x=“1111”,变量提升了,打印y报错是不是证明了let声明变量也存在变量提升了啊,不然话打印y,应该显示global才对。
看完上面所说的,我想你应该知道了,let也有变量提升,再来看看报错的内容,在初始化之前不能访问y,这就是所谓的let的"暂时性死区",let声明的变量,声明之前不可以被访问。
我们来看看,var声明变量的 创建 初始化 赋值的过程,假设有如下代码
function fn(){
var x = 1;
var y = 1;
}
fn()
- 先是在内存中创建变量x 和 y
- 然后在将这些变量初始化为undifind
- 然后才执行函数里的代码,进行赋值操作
再来看看let的
{
let x = 1
x = 2
}
- 找到let声明的变量,在内存中创建这些变量
- 然后开始执行代码,注意这里还没有进行初始化操作
- let x = 1,这一步是初始化操作,将x初始化为1
- x = 2 ,这一步是赋值操作
总结一下
var声明的变量,创建和初始化阶段都被提升了
let声明的变量,创建阶段被提升了,初始化阶段没有提示