攤平巢狀條件有兩條路:guard clause 省求值,重複條件換平行
巢狀條件要攤平,但攤平的方式不只一種,兩種各有代價。
// before
if (a) {
if (b) return 1
else return 2
} else {
return c
}// 路線一:重複條件,換「分支平行」
if (a && b) return 1
if (a && !b) return 2
return c
// 路線二:guard clause,換「只求值一次」
if (!a) return c
return b ? 1 : 2取捨
| 路線一(重複條件) | 路線二(guard clause) | |
|---|---|---|
| 換到的 | 每個分支同一層、各自讀得懂,像一張條件表 | a 只出現一次、不重複求值 |
| 付出的 | a 重複出現並被求值兩次,讀者要自己推「第二行隱含 a 成立」 | b 的決定降了一層 |
路線一的前提和 條件抽成變數還是 function,判準是求值時機與規模 一樣:條件求值便宜且沒有 side effect。否則重複求值不只是浪費,而是語意不同。
共同的目的
兩條路都不是為了「消滅 nested」本身,而是為了讓每一行只講一件事。原本那段 before 的問題是:讀者要同時記住 a 和 b 兩層狀態才知道自己在哪裡。
書上的標準形式則是把一連串條件換成 early return:
function getPayAmount() {
if (isDead) return deadAmount()
if (isSeparated) return separatedAmount()
if (isRetired) return retiredAmount()
return normalPayAmount()
}