网上很多博客和资料都写let和const不存在变量提升,只有var会产生变量提升,之前我一直对此深信不疑,直到看到大佬的文章开始对此产生了一点怀疑。
在理解这个问题之前,首先看看var let const的定义和区别。
var
在ES5前声明变量只能用var,且只存在函数作用域:
var message = "hi";
message = 100; //可以改变变量类型,合法但不推荐
age = 18; //不用var声明,代表全局变量
var存在变量提升:
//变量age自动提升到函数作用域顶部
function foo(){
console.log(age);
var age = 26;
}
foo();
//等同于如下的代码:
function foo(){
var age; //先声明,并赋值成undefined
console.log(age);
age = 26;
}
foo(); //undefined
let / const
let使得javascript具有块级作用域,const与let的唯一区别就是它在声明变量时必须同时初始化变量,且不能修改const声明的变量的值。
红宝书中文第四版P26中提到let与var的一个重要区别就是let存在暂时性死区,且let声明的变量不会在作用域中被提升
暂时性死区:在let声明之前的执行瞬间都被称为暂时性死区TDZ,在此阶段引用的任何后面才声明的变量都会抛出ReferenceError没有定义的错误。
//暂时性死区
console.log(name); //ReferenceError:name没有定义
let name = 'Jack';
但是仔细翻翻红宝书P92中提到:
let在JavaScript运行中实际上会被提升,但由于“暂时性死区”的存在,不能在声明中使用let变量
也就是说let / const 实际上是存在变量提升的,但是由于暂时性死区的存在使let / const不能在声明之前被使用,这与var的变量提升不太一样。
所以,说let / const 不存在变量提升是不完全正确的,只能说由于暂时性死区的存在使得我们无法直观感受到变量提升的效果。