JavaScript 變數提升 (Hoisting)
變數提升是 JavaScript 的預設行為,它會將宣告移動到頂部。
JavaScript 宣告會被提升
在 JavaScript 中,變數可以在宣告之後使用。
換句話說,變數可以在宣告之前使用。
示例 1 和 示例 2 的結果相同
示例 1
x = 5; // 給 x 賦值 5
elem = document.getElementById("demo"); // 找到一個元素
elem.innerHTML = x; // 在元素中顯示 x
var x; // 宣告 x
自己動手試一試 »
示例 2
var x; // 宣告 x
x = 5; // 給 x 賦值 5
elem = document.getElementById("demo"); // 找到一個元素
elem.innerHTML = x; // 在元素中顯示 x
自己動手試一試 »
要理解這一點,您必須理解“變數提升”這個術語。
變數提升是 JavaScript 的預設行為,它會將所有宣告移動到當前作用域的頂部(當前指令碼或當前函式的頂部)。
let 和 const 關鍵字
使用 let
和 const
定義的變數會被提升到塊的頂部,但不會被 *初始化*。
這意味著:程式碼塊知道該變數,但在宣告之前無法使用它。
在宣告之前使用 let
變數會導致 ReferenceError
。
變數處於“暫時性死區”(temporal dead zone),從程式碼塊開始直到宣告之前。
在宣告之前使用 const
變數會導致語法錯誤,因此程式碼根本不會執行。
在 JS Let / Const 中閱讀更多關於 let 和 const 的資訊。
JavaScript 初始化不會被提升
JavaScript 只提升宣告,而不提升初始化。
示例 1 與 示例 2 的結果不相同
示例 1
var x = 5; // 初始化 x
var y = 7; // 初始化 y
elem = document.getElementById("demo"); // 找到一個元素
elem.innerHTML = x + " " + y; // 顯示 x 和 y
自己動手試一試 »
示例 2
var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 找到一個元素
elem.innerHTML = x + " " + y; // 顯示 x 和 y
var y = 7; // 初始化 y
自己動手試一試 »
最後一個示例中 y 是 undefined,這是否合乎情理?
這是因為只有宣告(var y)被提升到頂部,而不是初始化(=7)。
由於變數提升,y 在使用之前已經被宣告,但由於初始化沒有被提升,所以 y 的值是 undefined。
示例 2 等同於以下寫法
示例
var x = 5; // 初始化 x
var y; // 宣告 y
elem = document.getElementById("demo"); // 找到一個元素
elem.innerHTML = x + " " + y; // 顯示 x 和 y
y = 7; // 給 y 賦值 7
自己動手試一試 »
在頂部宣告您的變數!
變數提升是(許多開發者)不知道或忽略的 JavaScript 行為。
如果開發者不理解變數提升,程式可能會包含 bug(錯誤)。
為避免 bug,請始終在每個作用域的開頭宣告所有變數。
由於 JavaScript 以這種方式解析程式碼,所以這始終是一個好規則。
JavaScript 的嚴格模式不允許使用未宣告的變數。
在下一章中學習 "use strict"。