其實(shí)你可以少寫點(diǎn)if else與switch(推薦)
前言
作為搬磚在第一線的底層工人,業(yè)務(wù)場景從來是沒有做不到只有想不到的復(fù)雜。
不過他強(qiáng)任他強(qiáng),if-else全搞定,搬就完了。但是隨著業(yè)務(wù)迭代或者項(xiàng)目交接,自己在看自己或者別人的if代碼的時候,心情就不再表述了,各自深有體會。所以我們一起看看if還能怎么寫
最基本if-else
假設(shè)有這么個場景,不同情況下打印不同值。
因?yàn)樯婕暗降臈l件太多,就不提三目運(yùn)算之類優(yōu)化了。
if (a == 1) { console.log('a1') } else if (a == 2) { console.log('b2') } else if (a == 3) { console.log('c3') } else if (a == 4) { console.log('d4') } /* n..... */
現(xiàn)在還算能看,因?yàn)檫壿嫼唵危绻壿嫃?fù)雜,迭代多個版本之后,你還敢動嗎。
每動一下就戰(zhàn)戰(zhàn)兢兢,誰知道哪里會遺漏。
那么換種方式呢
switch-case
這樣稍微清晰那么一點(diǎn),差別好像沒什么差別:
switch(a){ case 1: console.log('a1'); break; /* 省略。。。 */ case 40: console.log('a40'); break; }
分離配置信息與執(zhí)行動作
object映射
定義一個object作為配置對象來存放不同狀態(tài),通過鏈表查找
const statusMap = { 1:()=>{ console.log('a1') }, 2:()=>{ console.log('b2') } /* n.... */ } // 執(zhí)行 let a = 1 statusMap[a || 1]()
這樣比較清晰,將條件配置與具體執(zhí)行分離。如果要增加其他狀態(tài),只修改配置對象即可。
數(shù)組映射
當(dāng)然在某些狀態(tài)下可以使用數(shù)組,來做這個配置對象。
// 這里就涉及其他優(yōu)化了,例如將執(zhí)行函數(shù)抽離出來,大家不要關(guān)注func的內(nèi)容就好。 // 它就是個function,內(nèi)容很復(fù)雜 const statusArr = [function(){ console.log(1) }, function () { console.log(2) },] // 執(zhí)行 let a = 1 statusArr[a || 1]()
數(shù)組的要求更高一點(diǎn),如果是其他key,例如字符串,那么數(shù)組就不能滿足需求了
升級版:不同key相同value
這樣看起來好一點(diǎn)了,那么需求又有變動了,
前面是每種處理方式都不同,下面有幾種情況下處理函數(shù)相同的,
例如1-39的時候,調(diào)用a,40之后調(diào)用b,如果我們繼續(xù)來用映射的方式來處理。
function f1 (){ console.log(1) } function f2 (){ console.log(2) } const statusMap={ 1:f1, 2:f1, 3:f1, 4:f1, //省略 40:f2 } let a = 2 statusMap[a]()
這樣當(dāng)然也可以,不過重復(fù)寫那么多f1,代碼看起來不夠簡潔。
開始重構(gòu)之前我們先捋一下思路,無非是想把多個key合并起來,對應(yīng)一個value。
也就是說我們的鍵值不是字符串而是個數(shù)組,object顯然只支持字符串,
那么可以將這么多key合并成一個:'1,2,3,4,..,9'。
但是查找的時候有點(diǎn)問題了,我們的參數(shù)肯定不能完全匹配。
接著走下去,是不是做個遍歷加個判斷,包含在子集內(nèi)的都算匹配,那么代碼看起來就是下面這個樣子。
// 將鍵值key設(shè)置為一個拼接之后的字符串 const statusMap = { '1,2,3,4,5': f1, //省略 40: f2 } // 獲取所有的鍵值,待會遍歷用 const keys = Object.keys(statusMap), len = keys.length // 遍歷獲取對應(yīng)的值 const getVal=(param='')=>{ // 用for循環(huán)的原因在于匹配之后就不需要繼續(xù)遍歷 for (let i = 0; i < len; i++) { const key = keys[i], val = statusMap[key] // 這里用什么來判斷就隨便了,兩個字符串都有。 if (key.includes(param)) { return val } } } let a = 2, handle = getVal(a) handle() // 1
但是這樣來看,增加了個遍歷的過程,而且是拼接字符串,萬一哪天傳了個逗號進(jìn)來,會得到了預(yù)料之外的結(jié)果。
map
es6有個新的數(shù)據(jù)結(jié)構(gòu)Map,支持任意數(shù)據(jù)結(jié)構(gòu)作為鍵值。如果用Map可能更清晰一點(diǎn)。
/** * map鍵值索引的是引用地址, * 如果是下面這樣的寫法不好意思,永遠(yuǎn)得不到值 * map1.set([1,4,5],'引用地址') * map1.get([1,4,5]) //輸出為undefined * 就像直接訪問 * map1.get([1,2,3,4,5]) //同樣為undefined */ const map1 = new Map() const statusArr = [1,2,3,4,5] map1.set(statusArr,f1) // 預(yù)設(shè)默認(rèn)值,因?yàn)椴荒苤苯颖闅v let handle = function(){} const getVal = (param = '') => { for (let value of map1.entries()) { console.log(JSON.stringify(value)) if (value[0].includes(param)){ console.log(value) // 不能跳出 只能處理了 handle = value[1] } } } const a = 2 getVal(a) handle()
個人而言雖然這樣減少了重復(fù)代碼,但是又增加了一步匹配值的操作,優(yōu)劣就見仁見智吧。
二維數(shù)組
肯定有部分人就是不想做遍歷的操作,既然一個數(shù)組不能滿足,那么兩個數(shù)組呢。
// 鍵值數(shù)組和value 保持對應(yīng)關(guān)系 const keyArr = ['1,2,3,4,5','40'] const valArr = [f1,f2] const getVal = (param = '')=>{ // 查找參數(shù)對應(yīng)的下標(biāo) let index = keyArr.findIndex((it)=>{ return it.includes(param) }) // 獲取對應(yīng)值 return valArr[index] } let a = 2, handle = getVal(a) handle()
利用數(shù)組提供的下標(biāo),將key和value對應(yīng)起來,進(jìn)而獲取想要的值。
這里一直沒有達(dá)到我最初的目的,即鍵里面重復(fù)的數(shù)組,可以不通過多余操作匹配到,上面不管怎么樣都進(jìn)行了處理,這不是懶人的想要的。
總結(jié)
這是在寫業(yè)務(wù)需求的時候做的一點(diǎn)總結(jié),數(shù)組和對象的映射可能大家都在用。當(dāng)遇到了不同key相同value的情況時,從懶出發(fā)不像重復(fù)羅列,就嘗試了下。當(dāng)然了,因?yàn)閭€人水平問題,肯定有更好的處理方式,歡迎一起討論,拋磚引玉共同進(jìn)步。此外現(xiàn)有成熟的庫里loadsh也是可以到達(dá)目的,不過自己思考過之后再去看大神的作品理解會更深入一點(diǎn)。
相關(guān)文章
javascript實(shí)現(xiàn)的字符串與十六進(jìn)制表示字符串相互轉(zhuǎn)換方法
這篇文章主要介紹了javascript實(shí)現(xiàn)的字符串與十六進(jìn)制表示字符串相互轉(zhuǎn)換方法,涉及javascript字符串轉(zhuǎn)換的相關(guān)技巧,在防止SQL注入和XSS中具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07CSS中position屬性之fixed實(shí)現(xiàn)div居中
這篇文章主要介紹了CSS中position屬性之fixed實(shí)現(xiàn)div居中的相關(guān)資料,需要的朋友可以參考下2015-12-12js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊文本框自動選中內(nèi)容的方法
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊文本框自動選中內(nèi)容的方法,涉及javascript鼠標(biāo)點(diǎn)擊事件onClick及選擇事件select的使用技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-08-08js 實(shí)現(xiàn)watch監(jiān)聽數(shù)據(jù)變化的代碼
這篇文章主要介紹了js 實(shí)現(xiàn)watch監(jiān)聽數(shù)據(jù)變化的代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-10-10javascript 中模板方法單例的實(shí)現(xiàn)方法
這篇文章主要介紹了javascript 中模板方法單例的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10微信小程序?qū)崙?zhàn)之網(wǎng)易云音樂歌曲詳情頁實(shí)現(xiàn)代碼
本文給大家介紹了微信小程序?qū)W習(xí)記錄之網(wǎng)易云音樂歌曲詳情頁代碼實(shí)現(xiàn),代碼分為html、css和js部分,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05細(xì)說webpack源碼之compile流程-rules參數(shù)處理技巧(2)
這篇文章主要介紹了webpack源碼之compile流程-rules參數(shù)處理技巧的相關(guān)知識,需要的朋友參考下吧2017-12-12