JavaScript Hoisting 筆記
JavaScript 在建立執行環境的時候,會分為兩個階段
- 創造階段
- 執行階段
在創造階段的時候,會先靜態解析程式碼,找出 變數宣告與函數宣告,先替他們預留記憶空間,其中
- 函數 : 完整的函數程式碼都先放入記憶體
- 變數 : 先宣告並準備記憶體空間,但值還是 undefined,執行階段才會賦值
這種作法就會形成一種把所有函數都放在程式碼最前面執行的錯覺
console.log(myName); // undefined
// 而非 Uncaught ReferenceError: myName is not defined
greeting(); // Hi
var myName = "Alex";
function greeting() {
console.log("Hi");
}
var x = 1
會被拆解成
var x
: 在創造階段先宣告
x = 1
: 在執行階段賦值
函數陳述式、函數表達式
var fn = function () {
console.log("這是函數表達式");
// 像是把一個匿名函數 塞進 一個變數裡
};
function fn() {
console.log("這是函數陳述式");
// 最一開始接觸的函數宣告方式
}
fn(); // 這是函數表達式
明明 function fn()
在比較後面宣告,為什麼最後還是輸出 「這是函數表達式」呢?
我們來拆解以下步驟 :
- 創造階段開始
- 指派
function fn (){...}
完整內容 - 宣告
var fn
( 未賦值 ) - 執行階段開始
- 將
function ()
內容,賦值到fn
變數,因為執行階段才開始賦值 - 執行
fn()
,輸出 「這是函數表達式」
let
、const
TDZ
前段提到 var
有提升的效果,在變數宣告前就先取用變數的話會是 undefined
,而非 Uncaught ReferenceError
console.log(myName);
var myName = "Alex";
但是 let
和 const
可就不是這樣了
console.log(myName); // Cannot access 'myName' before initialization
let myName = "Alex";
Temporal dead zone 指的是,若在 let
/ const
宣告以前的區域,就試圖取得變數,會跳出錯誤,提醒你不要用這麼不符合邏輯的方式進行開發
Reference
帶你無痛提升 JavaScript 面試力 - Chapter 1 卡斯伯著