iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
Modern Web

我的JavaScript日常系列 第 22

JavaScript Day 22. Hoisting

在 JavaScript 裡還有一個概念稱為「Hoisting ( 提升 )」,底下先執行一段範例:

console.log(a)
// ReferenceError: a is not defined

當還沒有宣告變數的時候,JavaScript 也不會知道你要他執行什麼,於是當然會拋出錯誤;那麼如果我們改成寫這樣:

console.log(a) // undefined
var a

我們會發現他不是拋出錯誤,而是給了一個 undefined,而實際上這樣的結果,我們就稱他為「Hoisting ( 提升 )」。但現在我們會很納悶,JavaScript 不是有所謂的運行順序嗎?照上面這個範例來看,明明不是先宣告變數,卻仍然會回傳值?

剛剛說這種情況就是所謂的「Hoisting ( 提升 )」,而「Hoisting ( 提升 )」的概念主要是在說變數、函式在宣告期間就會先建立一個記憶體空間,而這個記憶體空間就是全域記憶體( Global Memory ) 或稱記憶體堆積(Heap),等到實際運行時再將值放入到這個記憶體空間內,因此我們可以理解到為什麼上面這個範例會回傳 undefined

另外有一點要注意的是,只有變數的宣告會提升,賦值不會。以下面這個範例為例:

console.log(a) // undefined
var a = 5

可以直接把他拆開來看:

var a
console.log(a) // undefined
a = 5

分成兩個階段,第一階段宣告變數 var a 的時候被提升了,第二階段 a = 5 賦值則不會被提升。

let 與 const 是否也有提升的動作?

letconst 是 ES6 之後新產生的兩個宣告變數的方法,那麼他會不會也有提升的行為呢,來看一下底下的範例:

console.log(a) // ReferenceError: a is not defined
let a

上面的範例我們會以為 letconst 沒有提升行為,但其實是有的,只是提升後的行為與 var 不太一樣:

var a = 10
function test(){
  console.log(a)
  let a
}
test()

這個範例的意思是說,假如 letconst 沒有提升行為,那輸出應該會是 10,但最後執行的結果是 ReferenceError: a is not defined,因此可以斷定 letconst 也有提升行為。

參考資料:

JS 原力覺醒 Day06 - 提升 Hoisting
我知道你懂 hoisting,可是你了解到多深?


上一篇
JavaScript Day 21. 陳述式 & 表達式
下一篇
JavaScript Day 23. flatMap()
系列文
我的JavaScript日常31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言