一天,我想更新一段看起來「再普通不過」的 JavaScript,我想新增個error的case,並且設置message變數:
switch (status) {
case 'success':
const message = 'OK';
console.log(message);
break;
//新增的code
case 'error':
const message = 'Fail';
console.log(message);
break
}
結果,專案直接噴錯。
SyntaxError: Identifier 'message' has already been declared
當下的我滿臉問號:
「這不是很正常的寫法嗎?」
直到我意識到一件事——
👉 switch case 其實沒有你想像中的「區塊作用域」。
case,其實不是一個 block
很多人(包含我)會直覺認為這樣:
case 'success': // 一個 scope
case 'error': // 另一個 scope
但實際上,JavaScript 不是這樣運作的。
👉 switch 裡的所有 case,共用同一個作用域(scope)
所以你其實寫了兩次:
const message = 'OK';const message = 'Fail';
然後 JavaScript 很合理地炸給你看。
修正方式很簡單
只要加上 {},事情就解決了:
switch (status) {
case 'success': {
const message = 'OK';
console.log(message);
break;
}
case 'error': {
const message = 'Fail';
console.log(message);
break;
}
}
這個 {} 的意義不是「排版」,而是 建立 block scope
可怕的是:這種 bug 很「隱性」
不像語法錯誤會立刻報錯,有些情況甚至會:
- 在某些 case 才出現
- 在 refactor 後才爆
- 或被其他變數名稱影響
這讓它變成一種典型的:
👉 「看起來沒問題,但其實很危險」的寫法
可讀性其實也在偷偷變差
很多人會覺得省略 {} 比較乾淨:
case 'success':
doSomething();
doAnotherThing();
break;
但當邏輯變多時:
- 範圍變得不明確
- 更容易漏
break - 更難做局部 refactor
ESLint 其實早就幫你踩煞車了
如果你有用 ESLint,很可能已經看過這個警告:
Unexpected lexical declaration in case block
對應規則是:
{ "rules": { "no-case-declarations": "error" }}
👉 它在告訴你一件事:
你應該用
{}包住 case」
總結
在寫程式的過程中,我們很容易追求一種「簡潔感」——
越少的程式碼、越精簡的寫法,彷彿就代表越高的技術水準。
像是省略 {},乍看之下乾淨俐落,甚至帶點「高手感」。
但實際上,這類非必要的簡略,往往只是把複雜性藏了起來。
它可能帶來:
- 難以察覺的作用域問題
- 以及在未來擴充時的潛在限制
這些問題不一定會立刻出現,但一旦發生,往往更難排查,也更難維護。
程式碼的價值,從來不只是「看起來簡潔」,
而是能否在時間的推移下,依然穩定、清晰、可擴展。
所以在選擇這些看似酷炫的簡寫時,我們更應該問自己兩個問題
1.這樣的寫法,是否隱藏了我還沒意識到的坑?
2.未來的我(或團隊),能不能輕鬆地在這段程式碼上繼續擴展?
當答案不夠明確時,或許多寫一對 {},反而才是更成熟的選擇。



















