JavaScript 中的變量聲明有三種主要方式:var
、let
?和?const
。理解它們之間的差異對于編寫清晰、有效的代碼至關重要。本文將深入探討這三種聲明方式的區別、使用場景以及潛在的陷阱。
一、var
?關鍵字
1.1 特點
- 函數作用域:
var
?聲明的變量在函數內是局部變量,在函數外是全局變量。 - 變量提升:
var
?聲明的變量會被提升到其作用域的頂部,但不會初始化。
1.2 示例
console.log(a); // undefined
var a = 10;
console.log(a); // 10function testVar() {var b = 20;if (true) {var b = 30; // 同一作用域內變量重定義console.log(b); // 30}console.log(b); // 30
}testVar();
?
在上述示例中,a
?的聲明被提升到了腳本的頂部,但其初始化仍在原來的位置。b
?在函數?testVar
?內被重新聲明并賦值,兩個?b
?變量實際指向同一個變量。
二、let
?關鍵字
2.1 特點
- 塊作用域:
let
?聲明的變量在其所在的塊級作用域內有效。 - 無變量提升:
let
?聲明的變量不會被提升,必須在聲明后才能使用。 - 暫時性死區:在塊級作用域內,
let
?聲明的變量在聲明之前不可用。
2.2 示例
if (true) {console.log(c); // ReferenceError: c is not definedlet c = 10;console.log(c); // 10
}function testLet() {let d = 20;if (true) {let d = 30; // 塊級作用域內變量重定義console.log(d); // 30}console.log(d); // 20
}testLet();
?
在這個示例中,c
?在聲明之前不可用,導致了引用錯誤。d
?在?if
?塊內和塊外是兩個不同的變量。
三、const
?關鍵字
3.1 特點
- 塊作用域:
const
?聲明的變量在其所在的塊級作用域內有效。 - 不可重新賦值:
const
?聲明的變量一旦賦值后不能再更改。 - 無變量提升:與?
let
?類似,const
?聲明的變量不會被提升。 - 暫時性死區:
const
?聲明的變量在聲明之前不可用。
3.2 示例
if (true) {const e = 10;console.log(e); // 10// e = 20; // TypeError: Assignment to constant variable.
}const f = { value: 30 };
f.value = 40; // 允許修改對象屬性
console.log(f.value); // 40// f = { value: 50 }; // TypeError: Assignment to constant variable.
?
在這個示例中,e
?的值不能被重新賦值。f
?是一個對象,盡管對象的屬性可以被修改,但?f
?不能被重新賦值為另一個對象。
四、對比與選擇
4.1 作用域
var
:函數作用域或全局作用域。let
?和?const
:塊級作用域。
4.2 變量提升
var
:聲明提升,但不會初始化。let
?和?const
:沒有變量提升,存在暫時性死區。
4.3 重新賦值
var
?和?let
:可以重新賦值。const
:不可重新賦值,但對象的屬性可變。
4.4 使用建議
- 優先使用?
const
?聲明變量,確保變量不會被意外重新賦值。 - 需要重新賦值的變量使用?
let
。 - 避免使用?
var
,除非有特殊需求,因其作用域和提升行為可能導致難以調試的問題。
五、實際應用場景
5.1 使用?let
?和?const
?替代?var
在現代JavaScript代碼中,let
?和?const
?的使用逐漸取代了?var
。以下是一個重構示例:
// 舊代碼使用 var
function exampleVar() {var name = 'Alice';var age = 25;console.log(name, age);
}// 新代碼使用 let 和 const
function exampleLetConst() {const name = 'Alice';let age = 25;console.log(name, age);
}
?
5.2 塊級作用域中的使用
在循環中使用?let
?避免全局變量污染:
for (let i = 0; i < 5; i++) {setTimeout(() => console.log(i), 1000);
}
?
在這個示例中,let
?保證了每次循環的?i
?都是獨立的,而不是共享一個全局變量。