我可以在宣告 JavaScript 變數之前使用它嗎?
是的,您可以使用一種稱為**提升 (hoisting)** 的技術在宣告 JavaScript 變數之前使用它。解析器會在執行程式碼之前讀取整個函式。
變數在宣告之前似乎就被使用了,這種行為被稱為提升。
例如,以下程式碼:
rank = 5; var rank;
以上程式碼與以下程式碼效果相同:
var rank; rank = 2;
JavaScript 中的提升允許我們宣告變數、函式或類,這些變數、函式或類會在程式碼執行之前被移動到作用域的頂部,無論其作用域是區域性還是全域性。
JavaScript 在執行之前為所有變數和函式分配記憶體。請注意,提升指的是宣告,而不是初始化。
由於變數和函式在程式碼中宣告之前就被使用了,因此可能會出現意外錯誤。因此,不建議使用提升。提升對 `var`、`let` 和 `const` 的作用方式不同。我們可以詳細檢查以下內容。
首先,我們將檢查使用 `var` 進行提升的示例。稍後我們將詳細檢查變數提升。
示例
<!DOCTYPE html> <html> <body> <h4>Hoisting Example</h4> <p id="output"></p> <script> x = 10; // Assign 5 to x document.getElementById("output").innerHTML = x; var x; // Declare x </script> </body> </html>
在這裡,我們可以看到我們在宣告 `x` 變數之前使用了它。
現在,我們將檢查 JavaScript 只提升宣告,而不提升初始化。讓我們看另一個例子
示例
<!DOCTYPE html> <html> <body> <h3>Hoists only declarations</h3> <p id="output"></p> <script> x = 10; // initialize x document.getElementById("output").innerHTML = x + " , " + y; var x; // declare x var y = 20; // declare and initialize y </script> </body> </html>
在這裡,我們可以檢查提升意味著 `y` 需要在其使用之前進行初始化。但是 `y` 沒有初始化。所以,這並沒有提升。這就是為什麼 `y` 的值為 `undefined`。我們可以像示例 1 中提到的那樣正確編寫。
示例
<!DOCTYPE html> <html> <body> <h1>Hoists only declarations</h1> <p id="output"></p> <script> var x = 10; // Initialize x var y; // declare y document.getElementById("output").innerHTML = x + " , " + y; y = 20; // Initialize y </script> </body> </html>
在這裡,變數 `y` 已宣告,但在顯示之前未初始化。
JavaScript 只提升宣告,不提升初始化。
始終注意,在後臺,JavaScript 首先宣告變數併為其初始化值。在 JS 中,未宣告的變數在分配程式碼執行之前不存在。因此,未宣告的變數在執行賦值程式碼時被視為全域性變數。讓我們更深入地瞭解變數提升。
`let` 和 `const` 的提升
我們都知道 `let` 和 `const` 是塊作用域的,而不是函式作用域的。`let` 和 `const` 是在 ES6 中引入的。我們知道 ES6 不允許未宣告的值。如果我們嘗試在宣告之前使用變數,它將丟擲引用錯誤。與 `var` 不同,變數不會使用預設值進行初始化。讓我們看一個例子
示例
<!DOCTYPE html> <html> <body> <h3>Hoisting with let</h3> <p id="output"></p> <script> try{ document.getElementById("output").innerHTML = x; let x = "Hi"; } catch(err) { document.getElementById("output").innerHTML = err; } </script> </body> </html>
在這裡,我們可以觀察到我們試圖在宣告 `x` 變數之前訪問它的值。讓我們再看一個使用 `let` 的例子。
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with let</h2> <p id="result1"></p> <p id="result2"></p> <script> let x; document.getElementById("result1").innerHTML = x; x = 5; document.getElementById("result2").innerHTML = x; </script> </body> </html>
現在,讓我們檢查 `const`。
使用 `const` 進行提升
與 `let` 一樣,我們不能在宣告之前使用變數,而且我們不僅需要宣告變數,還需要為它們初始化值。否則,它將丟擲 `SyntaxError` 錯誤。讓我們看一個例子
示例
<!DOCTYPE html> <html> <body> <h1>Hoisting with const</h1> <p> It will throw Uncaought SyntaxError: Missing initializer in const declaration </p> <p> To see this error please open the Console of the browser </p> <p id="output"></p> <script> const x; document.getElementById("output").innerHTML = x; x = 5; document.write(x); </script> </body> </html>
在宣告時需要初始化值。
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with const</h2> <p id="output"></p> <script> try{ document.getElementById("output").innerHTML = x; const x = 5; }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
與上面的示例一樣,`const` 也不可能實現。它將丟擲一個引用錯誤。
現在,讓我們看看使用函式進行提升。
函式提升
函式提升允許我們在定義函式之前呼叫它。讓我們看一個例子
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function</h2> <p id="output"></p> <script> getName("Devika"); function getName(name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } </script> </body> </html>
如果函式表示式賦值給變數。輸出將取決於變數作用域。像這樣:
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as var</h2> <p id="output"></p> <script> try{ getName("Devika"); var getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as let</h2> <p id="output"></p> <script> try{ getName("Devika"); let getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
示例
<!DOCTYPE html> <html> <body> <h2>Hoisting with function as const</h2> <p id="output"></p> <script> try{ getName("Devika"); const getName = function (name) { document.getElementById("output").innerHTML = ("Employee name is " + name); } }catch(err){ document.getElementById("output").innerHTML = err; } </script> </body> </html>
在這裡我們可以觀察到,帶有變數的函式的工作方式不同。如果我們將函式表示式賦值為 `var`,我們將得到 `TypeError`,而對於 `let` 和 `const`,我們將得到 `ReferenceError`。
但是,在宣告之前使用函式是我們的個人喜好問題。
希望本教程能讓你瞭解 js 中的提升以及提升如何與變數和函式一起工作。