夜行手札

技術成長 · Web 開發 · JavaScript

var、let、const到底差在哪裡?

差在哪裡呢?
3 分鐘閱讀

剛開始學 JavaScript 時,最常遇到的問題之一就是:

宣告變數時,到底該用 varlet還是 const

它們都能建立變數,但在作用範圍、是否能重複宣告,以及能不能重新賦值等方面,都有明顯差異。

---

先看最基本的用法

JavaScript
var userName = "Dennis";
const age = 20; //永遠的 20 歲
let siteName = "夜行手記";

這三行都在建立變數,但代表的限制不同:

  • var:舊式變數宣告方式
  • let:變數之後可以重新賦值
  • const:變數建立後不能重新指定成其他值

目前實務上通常會優先使用 const(我初學都是直接let打天下XD),確定需要重新賦值時才使用 let,而 var 則較少出現在目前較新的程式或系統中。

---

一、能不能重新賦值?

let 可以重新賦值:

JavaScript
// 宣告 dennis 的名義年齡
let dennis = 26; 

// 看起來的年齡(正確年齡,永遠的 20 歲)
dennis = 20; 

console.log(dennis); // 輸出:20

const 不行:

JavaScript
const dennis = 26; 
dennis = 20; 
console.log(dennis); // 錯誤(Assignment to constant variable.)

Tips:什麼是重新賦值?

重新賦值就是把變數裡原本存放的內容,換成另一個值。

簡單來說,let 像是可以更換內容的盒子;const 則是盒子貼上封條後,內容就不能再換成另一個東西。

---

二、作用範圍不同

letconst 都具有區塊作用域(Block Scope)。

JavaScript
if (true) {
    let message = "晚安";
    const title = "夜行手記";
}

console.log(message); // 錯誤
console.log(title);   // 錯誤

它們只存在於 {} 這個區塊裡,離開區塊後就無法使用。

var 沒有區塊作用域:

JavaScript
if (true) {
    var message = "晚安";
}

console.log(message); // 晚安

即使 message 宣告在 if 裡面,外面仍然可以取得它。
不過要注意,var 並不是完全沒有作用域,因為它還是有函式作用域(Function Scope)。

Tips:什麼是區塊作用域(Block Scope)?

作用域可以理解成「這個變數能被使用的範圍」。

變數如果只存在於某個區塊,就像房間裡的物品,只能在房間內使用,離開房間後就拿不到了。

---

三、能不能重複宣告?

var 可以在相同範圍內重複宣告:

JavaScript
var count = 1;
var count = 2;

letconst 不行:

JavaScript
const count = 1;
const count = 2; // 錯誤
let dennis = 26;
let dennis = 20; 
// 錯誤:概念類似於在同一個範圍內,你已經建立了一個 dennis,就不能再設置第二個 dennis,畢竟每個 dennis 都是獨一無二的。

有了剛剛的範例,我們就知道為什麼會有人提到 var 是容易造成 bug 的原因之一。

比如當程式越來越龐大,如果某個變數不小心被重新宣告,原本的值可能會被覆蓋,且不一定能即時發現,更要命的是你用的 AI 可能也沒辦法馬上發現到這種細微問題。

---

四、const 宣告的物件能改嗎?

這裡是容易誤會的點。

const 限制的是變數不能指向另一個值,但不代表物件內容完全不能改。

JavaScript
const user = {
    name: "Dennis"
};

user.name = "IRyS"; 
console.log(user.name); //這裡user的name被改成IRyS了。

這段程式可以正常執行,因為 user 仍然指向同一個物件,只是物件裡的 name 被修改了。

但下面這樣就不行:

JavaScript
const user = {
    name: "Dennis"
};

user = {
    name: "Amy"
};
console.log(user.name); // 會發生錯誤。

因為這裡代表的是要讓 user 改成指向另一個新的物件。

---

實務上該怎麼選?

可以記住一個簡單原則:

JavaScript
const result = [];
let currentIndex = 0;

只要變數不需要重新賦值,就使用 const

確定變數之後會改變,例如計數器、狀態或索引,可以使用 let

至於 var,除非是在維護舊專案,或需要理解既有程式碼,否則新的程式通常不建議使用。

---

簡單整理

特性varletconst
可以重新賦值可以可以不可以
可以重複宣告可以不可以不可以
區塊作用域沒有
新程式是否建議使用較不建議建議優先使用

最後濃縮成懶人包:

預設使用 const,需要改值時使用 let,盡量避免使用 var

這樣不只能減少變數被意外修改的情況,也能讓程式碼的未來更明朗XD。