答案是No
,let
const
都不存在变量提升,但是存在暂时性死区
不信的话可以比较一下以下代码:
let a = 'code'
{
console.log(a) // code
}
let b = 'js'
{
console.log(b) // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 'css'
}
在解释let上述问题的同时,我们顺带了解下var和let的区别
作用域
function varTest() {
var x = 1;
if (true) {
var x = 2; // 同样的变量!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}
- let声明的变量只在其声明的
块或子块
中可用
(循环体中是可以引用在for声明时用let定义的变量,尽管let不是出现在大括号之间) - 而var声明的变量的作用域是
整个封闭函数
暂时性死区
function do_something() {
console.log(bar); // undefined
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
var bar = 1;
let foo = 2;
}
do_something()
- 通过 var 声明的变量被提升的同时也被初始化,并赋值 undefined;
- 通过 let 声明的变量直到它们的定义被执行时才初始化,在变量初始化前访问该变量会导致 ReferenceError,官方称:变量处在一个自块顶部到初始化处理的
暂时性死区
中
总结得:
- let 的「创建」过程被提升了,但是初始化没有提升。
- var 的「创建」和「初始化」都被提升了,赋值undefined
- function 的「创建」「初始化」和「赋值」都被提升了