let、const 提升的雷點

前言

今天看到一個題目,一開始我以為 undefined & undefined,結果竟然不是,所以這邊紀錄一下題目及答案。

題目

1
2
3
4
5
6
7
8
function sayHi() {
console.log(name);
console.log(age);
var name = 'Lydia';
let age = 21;
}

sayHi();

開始撞牆

一開始我以為答案是 undefined & undefined,但是實際執行呢?

實際結果是 undefined & ReferenceError

先講 var,我們都知道 JavaScript 有所謂的 hoisting,在預設情況下記憶體都會準備一個 undefined 的關鍵字。

1
2
console.log(name); // undefined
var name = 'jack';

更詳細可以看我之前寫的 hoisting 文章

但是在 ES6 所提供的 let、const 就有一點不太一樣,我們來看一下範例

1
2
console.log(name);
let name = 'jack';

此時我們會得到一個 ReferenceError

ReferenceError

這段話的意思是在還沒初始化之前不能使用這個變數,簡單來講就是電腦沒有提供給你預設的 undefined 的關鍵字,但是這並不代表它沒有 hoisting 特性,只是它的 hoisting 特性現在稱為暫時死區(TDZ)。

const 呢?

1
2
console.log(name);
const name = 'jack';

結果也是一樣的

ReferenceError

回到講它並不是沒有 hoisting 這邊,首先為什麼這樣講呢?我們可以來實際檢驗一下

這兩者比較一下

1
2
3
4
5
6
var a = 10
function test(){
console.log(a)
let a
}
test()

ReferenceError

1
2
3
4
5
var a = 10
function test(){
console.log(a)
}
test()

10

可以發現很奇妙的事情,我在裡面宣告 let 與不宣告其實是有差異的,這可以證明一件事情,letconst 是有 hoisting 特性的。

(題外話: 我忘記看哪一篇文章說會出現 ReferenceError: a is not defined,但是我不管怎麼用都出不來 QQ??)

補充

謝謝其他人提供原文,原來是這篇https://blog.techbridge.cc/2018/11/10/javascript-hoisting/,但是很奇怪的是我還是用不出來XD?