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

Day 80

Day 80

Npm 套件收納箱

Npm 套件收納箱

Beautifulsoup Basic (Python)

Beautifulsoup Basic (Python)


Comments