技術成長 · Web 開發 · JavaScript
var、let、const到底差在哪裡?
剛開始學 JavaScript 時,最常遇到的問題之一就是:
宣告變數時,到底該用var、let還是const?
它們都能建立變數,但在作用範圍、是否能重複宣告,以及能不能重新賦值等方面,都有明顯差異。
---
先看最基本的用法
var userName = "Dennis";
const age = 20; //永遠的 20 歲
let siteName = "夜行手記";這三行都在建立變數,但代表的限制不同:
var:舊式變數宣告方式let:變數之後可以重新賦值const:變數建立後不能重新指定成其他值
目前實務上通常會優先使用 const(我初學都是直接let打天下XD),確定需要重新賦值時才使用 let,而 var 則較少出現在目前較新的程式或系統中。
---
一、能不能重新賦值?
let 可以重新賦值:
// 宣告 dennis 的名義年齡
let dennis = 26;
// 看起來的年齡(正確年齡,永遠的 20 歲)
dennis = 20;
console.log(dennis); // 輸出:20const 不行:
const dennis = 26;
dennis = 20;
console.log(dennis); // 錯誤(Assignment to constant variable.)Tips:什麼是重新賦值?
重新賦值就是把變數裡原本存放的內容,換成另一個值。
簡單來說,let 像是可以更換內容的盒子;const 則是盒子貼上封條後,內容就不能再換成另一個東西。
---
二、作用範圍不同
let 和 const 都具有區塊作用域(Block Scope)。
if (true) {
let message = "晚安";
const title = "夜行手記";
}
console.log(message); // 錯誤
console.log(title); // 錯誤它們只存在於 {} 這個區塊裡,離開區塊後就無法使用。
但 var 沒有區塊作用域:
if (true) {
var message = "晚安";
}
console.log(message); // 晚安即使 message 宣告在 if 裡面,外面仍然可以取得它。
不過要注意,var 並不是完全沒有作用域,因為它還是有函式作用域(Function Scope)。
Tips:什麼是區塊作用域(Block Scope)?
作用域可以理解成「這個變數能被使用的範圍」。
變數如果只存在於某個區塊,就像房間裡的物品,只能在房間內使用,離開房間後就拿不到了。
---
三、能不能重複宣告?
var 可以在相同範圍內重複宣告:
var count = 1;
var count = 2;但 let 和 const 不行:
const count = 1;
const count = 2; // 錯誤
let dennis = 26;
let dennis = 20;
// 錯誤:概念類似於在同一個範圍內,你已經建立了一個 dennis,就不能再設置第二個 dennis,畢竟每個 dennis 都是獨一無二的。有了剛剛的範例,我們就知道為什麼會有人提到 var 是容易造成 bug 的原因之一。
比如當程式越來越龐大,如果某個變數不小心被重新宣告,原本的值可能會被覆蓋,且不一定能即時發現,更要命的是你用的 AI 可能也沒辦法馬上發現到這種細微問題。
---
四、const 宣告的物件能改嗎?
這裡是容易誤會的點。
const 限制的是變數不能指向另一個值,但不代表物件內容完全不能改。
const user = {
name: "Dennis"
};
user.name = "IRyS";
console.log(user.name); //這裡user的name被改成IRyS了。這段程式可以正常執行,因為 user 仍然指向同一個物件,只是物件裡的 name 被修改了。
但下面這樣就不行:
const user = {
name: "Dennis"
};
user = {
name: "Amy"
};
console.log(user.name); // 會發生錯誤。因為這裡代表的是要讓 user 改成指向另一個新的物件。
---
實務上該怎麼選?
可以記住一個簡單原則:
const result = [];
let currentIndex = 0;只要變數不需要重新賦值,就使用 const。
確定變數之後會改變,例如計數器、狀態或索引,可以使用 let。
至於 var,除非是在維護舊專案,或需要理解既有程式碼,否則新的程式通常不建議使用。
---
簡單整理
| 特性 | var | let | const |
|---|---|---|---|
| 可以重新賦值 | 可以 | 可以 | 不可以 |
| 可以重複宣告 | 可以 | 不可以 | 不可以 |
| 區塊作用域 | 沒有 | 有 | 有 |
| 新程式是否建議使用 | 較不建議 | 建議 | 優先使用 |
最後濃縮成懶人包:
預設使用const,需要改值時使用let,盡量避免使用var。
這樣不只能減少變數被意外修改的情況,也能讓程式碼的未來更明朗XD。