Hoisting(提升)

@yu19941994
@yu19941994
Published in
Nov 4, 2020

MDN文件中表示「Hoisting是用以釐清 JS 在執行階段內行文如何運行的思路」

1.為什麼要有 Hoisting?

「為了解決兩個函式相互調用」

譬如在 function A(){}中呼叫 function B{},

又在 function B(){}中呼叫 function A(){}

但,如何同時讓 A 在 B 之上,且 B 又在 A 之上呢?(好饒口)

2.為什麼 JS 是「直譯式語言」卻可以有 Hoisting?

「因為 JS 也有編譯器」

也就是說在執行 JS 時會先建立「執行環境(Execution context, EC)」,其中分兩階段 — 「創造階段」及「執行階段」

而 Hoisting 是在 「創造階段」發生的,「執行階段」則是一行行將程式碼執行下來

3.從一個函式的執行來看 Hoisting

在執行一個函式時,會產生「執行環境(Execution context, EC)」。

JS是單執行緒, 在執行函式時,是先進後出的,也就是說會產生「執行環境堆疊」,置放在最底層的是全域執行環境,當上面「後進的執行環境」依序處理完,才再處理下面一層的「執行環境」。

而執行環境有「Objective Variable」、「Scope Chain」、「this」這三個屬性

其中,Objective Variable 在創造階段,會做三件事:

  1. 建立參數物件(Argument Object)
  2. 函式宣告
  3. 變數宣告

「函式宣告」及「變數宣告」即為 Hoisting

此時的變數都只有給予記憶體空間,並未賦予值

一直到執行階段,Activation Object 才會將變數給值

4. var 有 Hoisting,那 let、const 呢?

var 的 hoisting 是讓變數配置記憶體空間,但並未賦予值,因此為 undefined

而 let、const 也是有 Hoisting 的。只是它不會是 undefined,而是會拋出 ReferenceError 錯誤,形成暫時性死區(Temporal Dead Zone, TDZ)。

*新手學前端,所紀錄僅為吸收網路文章後,所做的匯整筆記,有錯歡迎留言指正

參考文章:

--

--