Hoisting


Posted by Erica on 2021-04-05

在 JavaScript 中,把宣告的 變數函式 拉升到最上層,在被呼叫執行之前先存進記憶體,這個現象就叫做 「提升(hoisting)」。


一般來說,我們都會事先宣告變數,接著才會執行。
如果沒有宣告就執行的話,會得到 ReferenceError: a is not defined 的錯誤,因為 JavaScript 找不到這個名為 a 的變數。

console.log(a) // 'a is not defined'

假設一段程式在執行後接著宣告變數,依照上面敘述答案應該是 a is not defined,但是結果卻是 undefined ,Why ?

console.log(a) // undefined
var a

JavaScript 的運行分為「創造階段」和「執行階段」。
在創造環境時,會將宣告的變數拉升到最上面,這個現象就叫做提升。
雖然理解上是移動到最上面,實際上位置並沒有改變,也可以說是靠「想像」把變數移動到最上面,而移動的行為就是把變數存進記憶體裡。
要特別注意變數宣告和賦值不同,雖然提升了宣告,但賦值卻會留在原地「依序」等待被執行。

console.log(a)
var a = 2

創造階段:
var a

執行階段:
console.log(a) // undefined
a = 2

除了變數宣告外,「函式陳述式」也會被提升到創造階段,並且優先載入。

function fn () {
  console.log('apple')
}
fn()
function fn () {
 console.log('orange')
}
fn()

拆解:

創造階段:函式優先
function fn () {
  console.log('apple')
} 
function fn () {
  console.log('orange')
}
執行階段:
fn() // 第一次執行:orange
fn() // 第二次執行:orange

如果是「函式表達式」又是另外一種狀況:在執行階段,才會把函式內容指派給變數。

var fn = function () {
  console.log('小明')
}
fn()
function fn () {
 console.log('orange')
}
fn()

拆解:

創造階段:函式優先
function () {
  console.log('apple')
}
function fn () {
 console.log('orange')
}
var fn

執行階段:
fn = function () {
  console.log('apple')
}
fn() // 第一次執行:apple
fn() // 第二次執行:apple

為什麼需要 Hoisting?

Hoistion 最初的設計是為了實現函式互相傳遞,畢竟在開發時會不只有一個函式,如果每個函式都要事先宣告的話,不僅繁瑣而且不好使用,如果有 Hoisting 的話就可以在任何地方呼叫函示。


參考文章:我知道你懂 hoisting,可是你了解到多深?


#javascript







Related Posts

部署 (1) —— 建立 AWS EC2 主機及 SSH 連線

部署 (1) —— 建立 AWS EC2 主機及 SSH 連線

Day 93

Day 93

Hold Shift to Check Multiple Checkboxes

Hold Shift to Check Multiple Checkboxes


Comments