這項看似激進的建議,正越來越多地出現(xiàn)在現(xiàn)代 JavaScript 代碼規(guī)范(如 Airbnb 的部分推薦、函數(shù)式編程社區(qū)的最佳實踐)中。它并非要徹底消滅 else
,而是倡導一種更清晰、更易于維護的編碼范式。
理解這項規(guī)范背后的深層原因,將幫助我們寫出更高質(zhì)量、更具可讀性的代碼。這不僅僅是一個風格問題,更是一種思維方式的轉(zhuǎn)變。
問題的根源:else
帶來的認知負荷
if...else
結(jié)構(gòu)本身沒有錯,但當它被濫用,尤其是嵌套使用時,會顯著增加代碼的“認知負荷”。這意味著我們的大腦需要花費更多的精力去理解代碼的邏輯分支。
來看一個經(jīng)典的“意大利面條式”代碼:
function getDiscount(user) {
let discount = 0;
if (user.isLoggedIn) {
if (user.isVip) {
if (user.orderCount > 10) {
discount = 0.2;
} else {
discount = 0.1;
}
} else {
if (user.orderCount > 5) {
discount = 0.05;
} else {
// No discount for non-VIPs with few orders
}
}
} else {
// No discount for guests
}
return discount;
}
要弄清楚一個普通用戶能獲得多少折扣,我們需要在大腦中追蹤一個復雜的“決策樹”。每一個 else
都代表一個分支,分支越多、嵌套越深,代碼就越難理解和維護。
核心理念:快速返回
這項規(guī)范建議的核心,是推崇一種被稱為 “衛(wèi)語句(Guard Clauses)” 或 “快速返回(Early Return)” 的設計模式。
這種模式的指導思想是:在函數(shù)的開頭,優(yōu)先處理所有的異常、邊緣或無效情況,并立即返回。 這樣,函數(shù)的主體部分就可以專注于處理“快樂路徑(Happy Path)”,即最核心、最正常的邏輯。
讓我們用“快速返回”的思路重構(gòu)上面的例子:
看到了嗎?代碼發(fā)生了質(zhì)的變化:
- 扁平化結(jié)構(gòu):嵌套層級大大減少,代碼從一棵“樹”變成了一條“直線”。
- 降低認知負荷:我們可以像讀一個清單一樣閱讀代碼。檢查完一個條件,如果不滿足就結(jié)束。我們不需要在腦海中保留“如果…那么…否則…”的上下文。
- 關(guān)注點分離:函數(shù)的開頭部分是“防御性”的,負責過濾掉無效輸入。函數(shù)的主體部分則可以專注于核心業(yè)務邏輯,代碼意圖更加清晰。
- 可維護性增強:當我們需要增加一個新的條件(比如“黑名單用戶”),我們只需在函數(shù)的開頭添加一個新的衛(wèi)語句即可,而無需在復雜的
else
嵌套中找到正確的位置。
帶來的其他好處
除了降低認知負荷,這種編碼風格還有其他優(yōu)點:
1. 鼓勵使用更具表現(xiàn)力的數(shù)據(jù)結(jié)構(gòu)
有時,一長串的 if...else if...else
結(jié)構(gòu),實際上可以用更優(yōu)雅的數(shù)據(jù)結(jié)構(gòu)來代替,比如 Map
或?qū)ο笞置媪俊?/span>
else if
鏈:
function getAnimalSound(animal) {
if (animal === 'dog') {
return 'woof';
} else if (animal === 'cat') {
return 'meow';
} else if (animal === 'bird') {
return 'tweet';
} else {
return 'unknown';
}
}
Map
實現(xiàn):
這種方式將“數(shù)據(jù)”和“邏輯”清晰地分離開來,代碼更加聲明式,易于擴展。
2. 促進函數(shù)式編程思維
在函數(shù)式編程中,傾向于使用表達式(Expressions)而非語句(Statements)。三元運算符 (?:
) 和邏輯運算符 (&&
, ||
) 都是表達式,它們返回一個值。if...else
是一個語句,它不返回值。
使用三元運算符:
// 代替簡單的 if/else
const isFrontendDev = true;
const message = isFrontendDev ? "歡迎關(guān)注 FedJavaScript" : "推薦關(guān)注 FedJavaScript";
這并不是說要用三元運算符替代所有 if
,但對于簡單的賦值操作,它顯然更簡潔、更具表現(xiàn)力。
這不是一條死板的教條
需要強調(diào)的是,“禁止使用 else
”并不是一條必須無條件遵守的鐵律。它的真正目的是促使我們思考:
- 我的代碼是否存在過深的嵌套?
- 我是否可以應用“快速返回”模式來簡化邏輯?
- 這里是否可以用一個更合適的數(shù)據(jù)結(jié)構(gòu)或設計模式來代替冗長的條件判斷?
在某些非常簡單的、二元對立的情況下,一個清晰的 if...else
結(jié)構(gòu)可能仍然是最直觀的選擇。
if (isSuccess) {
handleSuccess();
} else {
handleError();
}
在這種情況下,強行移除 else
可能會讓代碼變得更難懂,那就得不償失了。
這項規(guī)范建議,實際上是在引導我們從“能用”的代碼,走向“好用、好讀、好維護”的代碼。它挑戰(zhàn)了我們的編碼習慣,迫使我們采用一種更線性、更扁平化的思維方式。
閱讀原文:原文鏈接
該文章在 2025/10/10 14:47:52 編輯過