為什么在大廠代碼庫里,幾乎看不到 switch 語句的存在?
閱讀一些大型公司(如 Google, Meta等)的前端代碼庫時,你可能會發現一個有趣的現象:switch 語句的出場率非常低,甚至在很多核心模塊中完全不見蹤影。
在追求可維護性、可擴展性和可讀性的項目中,switch 語句的弊端會逐漸顯現,甚至成為代碼“壞味道”的來源。

開放/封閉原則
軟件工程中有一個非常重要的設計原則——開放/封閉原則,它的核心思想是:
軟件實體(類、模塊、函數等)應該對擴展開放,對修改封閉。
換句話說就是:當需求變更,需要增加新功能時,我們應該通過增加新代碼來實現,而不是修改舊代碼。
現在,我們來看看 switch 是如何背離這一原則的。
假設我們有一個根據用戶角色(role)返回不同操作權限的函數:
function getPermissions(role) {
let permissions;
switch (role) {
case 'admin':
permissions = ['create', 'read', 'update', 'delete'];
break;
case 'editor':
permissions = ['create', 'read', 'update'];
break;
default:
permissions = [];
}
return permissions;
}但如果我們要增加一個新的‘協作者’(collaborator)角色”,就必須修改這個函數內部邏輯,增加一個新的 case:

這看起來似乎沒什么大不了,但在一個龐大的系統中,這樣的 switch 邏輯可能散落在多個文件、多個模塊中。
每次增加新功能,就得找出所有相關的 switch 語句并逐一修改,一旦遺漏一個地方,就可能會產生 Bug。
除此之外,switch 還存在一些其他問題:
- 代碼冗長和易錯:每個 case 都需要一個 break 來終止,忘記寫 break 會導致穿透問題
- 職責不單一:龐大的 switch 語句往往將許多不同場景的處理邏輯強行耦合在一個函數里
- 可讀性下降:當 case 超過 3-4 個時,switch 語句的體積會迅速膨脹
替代方案:擁抱對象和 Map
在 JavaScript 中,最常用、最簡單的替代方案就是使用對象或 Map 來進行策略映射。
方案一:對象字面量(最常用)
我們可以用一個對象來存儲角色和權限的映射關系。這也被稱為“字典模式”。
const permissionMap = {
admin: ['create', 'read', 'update', 'delete'],
editor: ['create', 'read', 'update']
};
function getPermissions(role) {
// 使用映射關系,并提供一個默認值
return permissionMap[role] || [];
}
// 只需要在這里“擴展”
permissionMap.collaborator = ['create', 'read'];增加 collaborator 角色時,我們不需要修改 getPermissions 函數,只需擴展 permissionMap 對象即可。
方案二:使用 Map 數據結構
Map 的鍵可以是任意類型(比如對象、函數),而不僅僅是字符串或 Symbol,在需要更靈活的鍵時,使用 Map 是更好的選擇。

在大型前端項目中,代碼的生命周期很長,會經歷無數次的需求變更和人員迭代,因此,代碼的可維護性和可擴展性是首要考慮的因素。
switch 語句因其天生違反“開放/封閉原則”的特性,使得代碼在面對變化時顯得脆弱。而對象/Map 映射和策略模式等替代方案,則能讓我們的代碼結構更富彈性、更易于擴展和維護。






















