有些人認(rèn)為數(shù)字就是一,你應(yīng)該總是用至少一個(gè)三元運(yùn)算符來(lái)代替任何單個(gè) if 語(yǔ)句。我并不這樣認(rèn)為,但我想強(qiáng)調(diào)一些擺脫常見的 if/else 意大利面條代碼的方法。
我相信很多開發(fā)人員很容易陷入 if/else 陷阱,不是因?yàn)槠渌鉀Q方案的復(fù)雜性,而是因?yàn)樗裱@樣的自然語(yǔ)言模式:if 執(zhí)行此操作, else 執(zhí)行此操作。
三元運(yùn)算符與 if/else 并沒有革命性的區(qū)別,因?yàn)樗鼈兌际菞l件操作,但三元運(yùn)算符會(huì)返回一個(gè)值,因此可以直接用于賦值。
const greaterThanFive = (8 > 5) ? 'yep' : 'nope';console.log(greaterThanFive); // 'yep'
基本模式只是一個(gè)條件,如果為真則返回一個(gè)值,如果為假則返回另一個(gè)值。
(condition) ? isTruthy : isFalsy
讓我們從一個(gè)場(chǎng)景開始,逐步了解不同解決方案的示例。
我們將從用戶輸入中獲取顏色,并需要將它們轉(zhuǎn)換為一些預(yù)設(shè)的顏色代碼來(lái)匹配,以便我們可以更改背景顏色。因此,我們將檢查顏色名稱字符串,并在匹配時(shí)設(shè)置顏色代碼。
const setBackgroundColor = (colorName) => { let colorCode = ''; if(colorName === 'blue') { colorCode = '#2196F3'; } else if(colorName === 'green') { colorCode = '#4CAF50'; } else if(colorName === 'orange') { colorCode = '#FF9800'; } else if(colorName === 'pink') { colorCode = '#E91E63'; } else { colorCode = '#F44336'; }; document.body.style.backgroundColor = colorCode;};
這個(gè) if/else 就完成了工作。但是我們背負(fù)著大量重復(fù)邏輯比較 colorName 和重復(fù)賦值 colorCode。
現(xiàn)在我們可以更恰當(dāng)?shù)貙⑵涓臑?nbsp;switch 語(yǔ)句。它更符合我們正在嘗試做的事情的概念;我們有幾種想要匹配的字符串情況,如果沒有一種情況匹配,則有一個(gè)默認(rèn)值。
const setBackgroundColor = (colorName) => { let colorCode = ''; switch(colorName) { case 'blue': colorCode = '#2196F3'; break; case 'green': colorCode = '#4CAF50'; break; case 'orange': colorCode = '#FF9800'; break; case 'pink': colorCode = '#E91E63'; break; default: colorCode = '#f44336'; }; document.body.style.backgroundColor = colorCode;};
但是 switch 仍然帶有大量我們可以不需要的樣板文件和重復(fù)代碼。
那么我們真正想要實(shí)現(xiàn)什么目標(biāo)呢?我們需要將十六進(jìn)制顏色代碼分配給顏色名稱,因此讓我們創(chuàng)建一個(gè)將顏色名稱作為鍵、將顏色代碼作為值的對(duì)象。然后我們可以使用 object[key] 通過顏色名稱查找顏色代碼。我們需要一個(gè)默認(rèn)值,因此如果沒有找到鍵,則返回默認(rèn)值的短三元運(yùn)算符將在創(chuàng)建對(duì)象的默認(rèn)部分時(shí)執(zhí)行此操作。
const colorCodes = { 'blue' : '#2196F3', 'green' : '#4CAF50', 'orange' : '#FF9800', 'pink' : '#E91E63', 'default': '#F44336'};const setBackgroundColor = (colorName) => { document.body.style.backgroundColor = colorCodes[colorName] ? colorCodes[colorName] : colorCodes['default'];};
現(xiàn)在我們有了一個(gè)查找表,可以整齊地列出我們的輸入和可能的輸出。
這并不是奇跡般地減少了“代碼行數(shù)”(LOC)(我們從 15 行減少到 20 行,再減少到 12 行)。事實(shí)上,其中一些解決方案可能會(huì)增加您的 LOC,但我們提高了可維護(hù)性、易讀性,并且實(shí)際上通過僅對(duì)默認(rèn)回退進(jìn)行一次邏輯檢查來(lái)降低復(fù)雜性。
在 if/else 或 switch 上使用查找表的最重要成就是我們將比較邏輯的多個(gè)實(shí)例轉(zhuǎn)換為數(shù)據(jù)。代碼更具表現(xiàn)力;它將邏輯顯示為操作。代碼更具可測(cè)試性;邏輯被減少了。而且我們的比較更容易維護(hù);它們被合并為純數(shù)據(jù)。
讓我們將五個(gè)比較邏輯運(yùn)算減少為一個(gè),并將我們的值轉(zhuǎn)換為數(shù)據(jù)。
場(chǎng)景:我們需要將成績(jī)百分比轉(zhuǎn)換為對(duì)應(yīng)的字母成績(jī)。
if/else 很簡(jiǎn)單;我們從上到下檢查成績(jī)是否高于或等于匹配字母成績(jī)所需的成績(jī)。
const getLetterGrade = (gradeAsPercent) => { if(gradeAsPercent >= 90) { return "A"; } else if(gradeAsPercent >= 80) { return "B"; } else if(gradeAsPercent >= 70) { return "C"; } else if(gradeAsPercent >= 60) { return "D"; } else { return "F" };};
但我們一遍又一遍地重復(fù)相同的邏輯運(yùn)算。
因此,讓我們將數(shù)據(jù)提取到一個(gè)數(shù)組中(以保留順序)并將每個(gè)等級(jí)的可能性表示為一個(gè)對(duì)象。現(xiàn)在我們只需對(duì)對(duì)象進(jìn)行一次 >= 比較,并找到數(shù)組中第一個(gè)匹配的對(duì)象。
const gradeChart = [ {minpercent: 90, letter: 'A'}, {minpercent: 80, letter: 'B'}, {minpercent: 70, letter: 'C'}, {minpercent: 60, letter: 'D'}, {minpercent: 0, letter: 'F'}];const getLetterGrade = (gradeAsPercent) => { const grade = gradeChart.find( (grade) => gradeAsPercent >= grade.minpercent ); return grade.letter;};
當(dāng)你需要比較或“檢查”數(shù)值時(shí),很自然地會(huì)想到 if/else,這樣你就可以用語(yǔ)言逐步解決問題。但下一次,請(qǐng)?jiān)囍伎既绾螌⒛闹当硎緸閿?shù)據(jù),并通過簡(jiǎn)化邏輯來(lái)解釋這些數(shù)據(jù)。
您的代碼最終將變得更具可讀性、可維護(hù)性和目的性,并且其所代表的概念清晰分離。
原文:https://dreith.com/blog/theres-such-a-thing-as-using-too-many-ifs/
本文鏈接:http://www.tebozhan.com/showinfo-26-80517-0.html我們一起聊聊如何簡(jiǎn)化多個(gè) if 的判斷結(jié)構(gòu)
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 深入理解Java虛擬機(jī):堆詳解