什麼是提升?
在 JavaScript 中,提升是指變數和函數宣告會在程式執行前被「提升」到它們所在作用域(scope)的頂部。這是 JavaScript 引擎處理程式碼時的一種行為,讓你在宣告之前就能使用某些變數或函數。
關鍵點
- 只提升宣告,不提升賦值
- 變數的宣告(比如 var x;)會被提升,但賦值(比如 x = 5;)不會。
- 函數宣告整個會被提升,包括函數名稱和內容。
- 適用於
var
,不完全適用於let
和const
var
宣告的變數會被提升,並初始化為undefined
。let
和const
也會被提升,但不會初始化,處於「暫時性死區」(Temporal Dead Zone),在宣告前使用會報錯。
- 函數宣告 vs 函數表達式
- 函數宣告(function foo() {})會完整提升,可以在宣告前呼叫。
- 函數表達式(var foo = function() {})只有變數部分提升,賦值不會提升,所以宣告前呼叫會出錯。
範例解析
範例 1:變數提升console.log(x); // 輸出:undefined
var x = 5;
console.log(x); // 輸出:5
實際執行時,JavaScript 會把 var x 提升到頂部,但 x = 5 留在原地。也就是說
var x;
console.log(x); // undefined
x = 5;
console.log(x); // 5
範例 2:let
和 const
的行為
console.log(x); // 報錯:ReferenceError
let x = 10;
console.log(y); // 報錯:ReferenceError
const y = 10;
被提升,但未初始化,宣告前使用會進入暫時性死區。
範例 3:函數提升
foo1(); // 輸出:Hello
function foo1() {
console.log("Hello");
}
foo2(); //TypeError: foo2 is not a function
var foo2 = function () {
console.log("Hello");
}
函數宣告(Function Declaration)整個被提升,所以可以在宣告前呼叫。
函數表達式(Function Expression)使用 var 所以只有變數名稱 foo2 被提升,賦值留在原地,所以宣告前調用會失敗。
注意事項
- 避免依賴提升:雖然提升是語言特性,但為了程式碼可讀性,最好在變數或函數使用前先宣告。
- 作用域影響:提升只在當前作用域內生效,比如函數內的宣告不會提升到全域。
小結
提升是 JavaScript 的獨特機制,理解它能幫助你避免常見錯誤(如 undefined 或 ReferenceError)。
重點:var 提升且初始化為 undefined,let 和 const 有暫時性死區,函數宣告完全提升。