答案是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 的「創建」「初始化」和「賦值」都被提升了