提升代碼可讀性,減少 if-else 的幾個(gè)小技巧
前言???♂?
相信大家或多或少都接觸過(guò)擁有龐大 if else 的項(xiàng)目代碼吧,多重嵌套的 if else 在維護(hù)的時(shí)候真的讓人很惱火??,有時(shí)候一個(gè) bug 排查下來(lái),嚴(yán)重感覺(jué)身體被掏空??。
本文并未有消滅或歧視 if else的意思,if else 的好用都知道,這里只是在某些特定場(chǎng)景為大家額外提供一種思路,增加我們代碼的可讀性??。
短路運(yùn)算??
Javascript 的邏輯或 || 的短路運(yùn)算有時(shí)候可以用來(lái)代替一些比較簡(jiǎn)單的 if else
邏輯或 ||的短路運(yùn)算:若左邊能轉(zhuǎn)成true,返回左邊式子的值,反之返回右邊式子的值。
下面用一個(gè)簡(jiǎn)單的案例來(lái)表述
let c
if(a){
c = a
} else {
c = b
}
復(fù)制代碼
大家看著上面的代碼會(huì)難受嘛(本人有一丟丟的強(qiáng)迫癥??),明明就是一個(gè)很簡(jiǎn)單的判斷卻需要寫(xiě)好幾行代碼才能實(shí)現(xiàn)。這個(gè)時(shí)候我們就可以用短路運(yùn)算去簡(jiǎn)化我們的代碼啦??。
let c = a || b
復(fù)制代碼
這樣看起來(lái)是不是就簡(jiǎn)潔了很多??。
三元運(yùn)算符??
三元運(yùn)算符我覺(jué)得大家應(yīng)該都很熟悉吧,很多時(shí)候簡(jiǎn)單的一些判斷我們都可以使用三元運(yùn)算符去替代 if else,這里只推薦 一層 三元運(yùn)算符,因?yàn)槎鄬忧短椎娜\(yùn)算符也不具備良好的可讀性??。
例子:條件為 true 時(shí)返回1,反之返回0:
const fn = (nBoolean) {
if (nBoolean) {
return 1
} else {
return 0
}
}
// 使用三元運(yùn)算符
const fn = (nBoolean) {
return nBoolean ? 1 : 0
}
復(fù)制代碼
三元運(yùn)算符使用的地方也比較多,比如:條件賦值,遞歸...
// num值在nBoolean為true時(shí)為10,否則為5
let num = nBoolean ? 10 : 5
// 求0-n之間的整數(shù)的和
let sum = 0;
function add(n){
sum += n
return n >= 2 ? add(n - 1) : result;
};
let num = add(10);//55
復(fù)制代碼
switch case???
上述的兩種方式:短路運(yùn)算跟三元運(yùn)算雖然很好用,代碼也很簡(jiǎn)潔,不過(guò)都只能用于簡(jiǎn)單的判斷,遇到多重條件判斷就不能使用了??。
對(duì)于 switch case,雖然它的可讀性確實(shí)比 else if 更高,但是我想大家應(yīng)該都覺(jué)得它寫(xiě)起來(lái)比較麻煩吧??(反正我覺(jué)得很麻煩??)。
例:有A、B、C、D四種種類(lèi)型,在A、B的時(shí)候輸出1,C輸出2、D輸出3,默認(rèn)輸出0。
let type = 'A'
//if else if
if (type === 'A' || type === 'B') {
console.log(1);
} else if (type === 'C') {
console.log(2);
} else if(type === 'D') {
console.log(3);
} else {
console.log(0)
}
//switch case
switch (type) {
case 'A':
case 'B':
console.log(1)
break
case 'C':
console.log(2)
break
case 'D':
console.log(3);
break;
default:
console.log(0)
}
復(fù)制代碼
對(duì)象配置/策略模式??
對(duì)象配置看起來(lái)跟 策略模式 差不多,都是根據(jù)不同得參數(shù)使用不同得數(shù)據(jù)/算法/函數(shù)。??
策略模式就是將一系列算法封裝起來(lái),并使它們相互之間可以替換。被封裝起來(lái)的算法具有獨(dú)立性,外部不可改變其特性。
接下來(lái)我們用對(duì)象配置的方法實(shí)現(xiàn)一下上述的例子
let type = 'A'
let tactics = {
'A': 1,
'B': 1,
'C': 2,
'D': 3,
default: 0
}
console.log(tactics[type]) // 1
復(fù)制代碼
接下來(lái)用幾個(gè)例子讓大家更加熟悉一點(diǎn)。
案例1 商場(chǎng)促銷(xiāo)價(jià)??
根據(jù)不同的用戶使用不同的折扣,如:普通用戶不打折,普通會(huì)員用戶9折,年費(fèi)會(huì)員8.5折,超級(jí)會(huì)員8折。
使用if else實(shí)現(xiàn)??
// 獲取折扣 --- 使用if else
const getDiscount = (userKey) => {
if (userKey === '普通會(huì)員') {
return 0.9
} else if (userKey === '年費(fèi)會(huì)員') {
return 0.85
} else if (userKey === '超級(jí)會(huì)員') {
return 0.8
} else {
return 1
}
}
console.log(getDiscount('普通會(huì)員')) // 0.9
復(fù)制代碼
使用對(duì)象配置/策略模式實(shí)現(xiàn)??
// 獲取折扣 -- 使用對(duì)象配置/策略模式
const getDiscount = (userKey) => {
// 我們可以根據(jù)用戶類(lèi)型來(lái)生成我們的折扣對(duì)象
let discounts = {
'普通會(huì)員': 0.9,
'年費(fèi)會(huì)員': 0.85,
'超級(jí)會(huì)員': 0.8,
'default': 1
}
return discounts[userKey] || discounts['default']
}
console.log(getDiscount('普通會(huì)員')) // 0.9
復(fù)制代碼
從上面的案列中可以明顯看得出來(lái),使用對(duì)象配置比使用if else可讀性更高,后續(xù)如果需要添加用戶折扣也只需要修改折扣對(duì)象就行??。
對(duì)象配置不一定非要使用對(duì)象去管理我們鍵值對(duì),還可以使用 Map去管理??,如:
// 獲取折扣 -- 使用對(duì)象配置/策略模式
const getDiscount = (userKey) => {
// 我們可以根據(jù)用戶類(lèi)型來(lái)生成我們的折扣對(duì)象
let discounts = new Map([
['普通會(huì)員', 0.9],
['年費(fèi)會(huì)員', 0.85],
['超級(jí)會(huì)員', 0.8],
['default', 1]
])
return discounts.get(userKey) || discounts.get('default')
}
console.log(getDiscount('普通會(huì)員')) // 0.9
復(fù)制代碼
案例2 年終獎(jiǎng)??
公司的年終獎(jiǎng)根據(jù)員工的工資基數(shù)和績(jī)效等級(jí)來(lái)發(fā)放的。例如,績(jī)效為A的人年終獎(jiǎng)有4倍工資,績(jī)效為B的有3倍,績(jī)效為C的只有2倍。
假如財(cái)務(wù)部要求我們提供一段代碼來(lái)實(shí)現(xiàn)這個(gè)核算邏輯,我們要怎么實(shí)現(xiàn)呢?
這不是很簡(jiǎn)單嘛,一個(gè)函數(shù)就搞定了。
const calculateBonus = (performanceLevel, salary) => {
if (performanceLevel === 'A'){
return salary * 4
}
if (performanceLevel === 'B'){
return salary * 3
}
if (performanceLevel === 'C'){
return salary * 2
}
}
calculateBonus( 'B', 20000 ) // 輸出:60000
復(fù)制代碼
可以發(fā)現(xiàn),這段代碼十分簡(jiǎn)單,但是 calculateBonus函數(shù)比較龐大,所有的邏輯分支都包含在if else語(yǔ)句中,如果增加了一種新的績(jī)效等級(jí)D,或者把A等級(jí)的倍數(shù)改成5,那我們必須閱讀所有代碼才能去做修改???♂?。
所以我們可以用對(duì)象配置/策略模式去簡(jiǎn)化這個(gè)函數(shù)??
let strategies = new Map([
['A', 4],
['B', 3],
['C', 2]
])
const calculateBonus = (performanceLevel, salary) => {
return strategies.get(performanceLevel) * salary
}
calculateBonus( 'B', 20000 ) // 輸出:60000
復(fù)制代碼
至此,這個(gè)需求做完了,然后產(chǎn)品經(jīng)理說(shuō)要加上一個(gè)部門(mén)區(qū)分,假設(shè)公司有兩個(gè)部門(mén)D和F,D部門(mén)的業(yè)績(jī)較好,所以年終獎(jiǎng)翻1.2倍??,F(xiàn)部門(mén)的業(yè)績(jī)較差,年終獎(jiǎng)打9折??。
改造以上代碼,把狀態(tài)值拼接,然后存入Map中
// 以績(jī)效_部門(mén)的方式拼接鍵值存入
let strategies = new Map([
['A_D', 4 * 1.2],
['B_D', 3 * 1.2],
['C_D', 2 * 1.2],
['A_F', 4 * 0.9],
['B_F', 3 * 0.9],
['C_F', 2 * 0.9]
])
const calculateBonus = (performanceLevel, salary, department) => {
return strategies.get(`${performanceLevel}_${department}`) * salary
}
calculateBonus( 'B', 20000, 'D' ) // 輸出:72000
復(fù)制代碼
結(jié)尾??
本文主要是向大家傳遞一種思想,我們有很多的方法去優(yōu)化我們的代碼,提高我們代碼的可讀性。
對(duì)if else并沒(méi)有歧視的意思,只是希望在大家以后的代碼中不僅僅只有if else??。
博客主要記錄一些學(xué)習(xí)的文章,如有不足,望大家指出,謝謝。
關(guān)于本文
作者:樹(shù)深遇鹿
https://juejin.cn/post/7153536318859903012
