亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

JS復雜判斷的更優雅寫法代碼詳解

2024-05-06 16:46:45
字體:
來源:轉載
供稿:網友

我們編寫js代碼時經常遇到復雜邏輯判的情況,通常大家可以用if/else或者switch來實現多個條件判斷,但這樣會有個問題,隨著邏輯復雜度的增加,代碼中的if/else/switch會變得越來越臃腫,越來越看不懂,那么如何更優雅的寫判斷邏輯,本文帶你試一下。

舉個例子

先看一段代碼

/** * 按鈕點擊事件 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消 */const onButtonClick1 = (status)=>{ if(status == 1){  sendLog('processing')  jumpTo('IndexPage') }else if(status == 2){  sendLog('fail')  jumpTo('FailPage') }else if(status == 3){  sendLog('fail')  jumpTo('FailPage') }else if(status == 4){  sendLog('success')  jumpTo('SuccessPage') }else if(status == 5){  sendLog('cancel')  jumpTo('CancelPage') }else {  sendLog('other')  jumpTo('Index') }}

通過代碼可以看到這個按鈕的點擊邏輯:根據不同活動狀態做兩件事情,發送日志埋點和跳轉到對應頁面,大家可以很輕易的提出這段代碼的改寫方案,switch出場:

/** * 按鈕點擊事件 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消 */const onButtonClick = (status)=>{ switch (status){  case 1:   sendLog('processing')   jumpTo('IndexPage')   break  case 2:  case 3:   sendLog('fail')   jumpTo('FailPage')   break   case 4:   sendLog('success')   jumpTo('SuccessPage')   break  case 5:   sendLog('cancel')   jumpTo('CancelPage')   break  default:   sendLog('other')   jumpTo('Index')   break }}

嗯,這樣看起來比if/else清晰多了,細心的同學也發現了小技巧,case 2和case 3邏輯一樣的時候,可以省去執行語句和break,則case 2的情況自動執行case 3的邏輯。

這時有同學會說,還有更簡單的寫法:

const actions = { '1': ['processing','IndexPage'], '2': ['fail','FailPage'], '3': ['fail','FailPage'], '4': ['success','SuccessPage'], '5': ['cancel','CancelPage'], 'default': ['other','Index'],}/** * 按鈕點擊事件 * @param {number} status 活動狀態:1開團進行中 2開團失敗 3 商品售罄 4 開團成功 5 系統取消 */const onButtonClick = (status)=>{ let action = actions[status] || actions['default'],   logName = action[0],   pageName = action[1] sendLog(logName) jumpTo(pageName)}

上面代碼確實看起來更清爽了,這種方法的聰明之處在于:將判斷條件作為對象的屬性名,將處理邏輯作為對象的屬性值,在按鈕點擊的時候,通過對象屬性查找的方式來進行邏輯判斷,這種寫法特別適合一元條件判斷的情況。

是不是還有其他寫法呢?有的:

const actions = new Map([ [1, ['processing','IndexPage']], [2, ['fail','FailPage']], [3, ['fail','FailPage']], [4, ['success','SuccessPage']], [5, ['cancel','CancelPage']], ['default', ['other','Index']]])/** * 按鈕點擊事件 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消 */const onButtonClick = (status)=>{ let action = actions.get(status) || actions.get('default') sendLog(action[0]) jumpTo(action[1])}

這樣寫用到了es6里的Map對象,是不是更爽了?Map對象和Object對象有什么區別呢?

一個對象通常都有自己的原型,所以一個對象總有一個"prototype"鍵。
一個對象的鍵只能是字符串或者Symbols,但一個Map的鍵可以是任意值。

你可以通過size屬性很容易地得到一個Map的鍵值對個數,而對象的鍵值對個數只能手動確認。

我們需要把問題升級一下,以前按鈕點擊時候只需要判斷status,現在還需要判斷用戶的身份:

/** * 按鈕點擊事件 * @param {number} status 活動狀態:1開團進行中 2開團失敗 3 開團成功 4 商品售罄 5 有庫存未開團 * @param {string} identity 身份標識:guest客態 master主態 */const onButtonClick = (status,identity)=>{ if(identity == 'guest'){  if(status == 1){   //do sth  }else if(status == 2){   //do sth  }else if(status == 3){   //do sth  }else if(status == 4){   //do sth  }else if(status == 5){   //do sth  }else {   //do sth  } }else if(identity == 'master') {  if(status == 1){   //do sth  }else if(status == 2){   //do sth  }else if(status == 3){   //do sth  }else if(status == 4){   //do sth  }else if(status == 5){   //do sth  }else {   //do sth  } }}

原諒我不寫每個判斷里的具體邏輯了,因為代碼太冗長了。

原諒我又用了if/else,因為我看到很多人依然在用if/else寫這種大段的邏輯判斷。

從上面的例子我們可以看到,當你的邏輯升級為二元判斷時,你的判斷量會加倍,你的代碼量也會加倍,這時怎么寫更清爽呢?

const actions = new Map([ ['guest_1', ()=>{/*do sth*/}], ['guest_2', ()=>{/*do sth*/}], ['guest_3', ()=>{/*do sth*/}], ['guest_4', ()=>{/*do sth*/}], ['guest_5', ()=>{/*do sth*/}], ['master_1', ()=>{/*do sth*/}], ['master_2', ()=>{/*do sth*/}], ['master_3', ()=>{/*do sth*/}], ['master_4', ()=>{/*do sth*/}], ['master_5', ()=>{/*do sth*/}], ['default', ()=>{/*do sth*/}],])/** * 按鈕點擊事件 * @param {string} identity 身份標識:guest客態 master主態 * @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 開團成功 4 商品售罄 5 有庫存未開團 */const onButtonClick = (identity,status)=>{ let action = actions.get(`${identity}_${status}`) || actions.get('default') action.call(this)}

上述代碼核心邏輯是:把兩個條件拼接成字符串,并通過以條件拼接字符串作為鍵,以處理函數作為值的Map對象進行查找并執行,這種寫法在多元條件判斷時候尤其好用。

當然上述代碼如果用Object對象來實現也是類似的:

const actions = { 'guest_1':()=>{/*do sth*/}, 'guest_2':()=>{/*do sth*/}, //....}const onButtonClick = (identity,status)=>{ let action = actions[`${identity}_${status}`] || actions['default'] action.call(this)}

如果有些同學覺得把查詢條件拼成字符串有點別扭,那還有一種方案,就是用Map對象,以Object對象作為key

const actions = new Map([ [{identity:'guest',status:1},()=>{/*do sth*/}], [{identity:'guest',status:2},()=>{/*do sth*/}], //...])const onButtonClick = (identity,status)=>{ let action = [...actions].filter(([key,value])=>(key.identity == identity && key.status == status)) action.forEach(([key,value])=>value.call(this))}

是不是又高級了一點點?

這里也看出來Map與Object的區別,Map可以用任何類型的數據作為key。

我們現在再將難度升級一點點,假如guest情況下,status1-4的處理邏輯都一樣怎么辦,最差的情況是這樣:

const actions = new Map([ [{identity:'guest',status:1},()=>{/* functionA */}], [{identity:'guest',status:2},()=>{/* functionA */}], [{identity:'guest',status:3},()=>{/* functionA */}], [{identity:'guest',status:4},()=>{/* functionA */}], [{identity:'guest',status:5},()=>{/* functionB */}], //...])

好一點的寫法是將處理邏輯函數進行緩存:

const actions = ()=>{ const functionA = ()=>{/*do sth*/} const functionB = ()=>{/*do sth*/} return new Map([  [{identity:'guest',status:1},functionA],  [{identity:'guest',status:2},functionA],  [{identity:'guest',status:3},functionA],  [{identity:'guest',status:4},functionA],  [{identity:'guest',status:5},functionB],  //... ])}const onButtonClick = (identity,status)=>{ let action = [...actions()].filter(([key,value])=>(key.identity == identity && key.status == status)) action.forEach(([key,value])=>value.call(this))}

這樣寫已經能滿足日常需求了,但認真一點講,上面重寫了4次functionA還是有點不爽,假如判斷條件變得特別復雜,比如identity有3種狀態,status有10種狀態,那你需要定義30條處理邏輯,而往往這些邏輯里面很多都是相同的,這似乎也是筆者不想接受的,那可以這樣實現:

const actions = ()=>{ const functionA = ()=>{/*do sth*/} const functionB = ()=>{/*do sth*/} return new Map([  [/^guest_[1-4]$/,functionA],  [/^guest_5$/,functionB],  //... ])}const onButtonClick = (identity,status)=>{ let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`))) action.forEach(([key,value])=>value.call(this))}

這里Map的優勢更加凸顯,可以用正則類型作為key了,這樣就有了無限可能,假如需求變成,凡是guest情況都要發送一個日志埋點,不同status情況也需要單獨的邏輯處理,那我們可以這樣寫:

const actions = ()=>{ const functionA = ()=>{/*do sth*/} const functionB = ()=>{/*do sth*/} const functionC = ()=>{/*send log*/} return new Map([  [/^guest_[1-4]$/,functionA],  [/^guest_5$/,functionB],  [/^guest_.*$/,functionC],  //... ])}const onButtonClick = (identity,status)=>{ let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`))) action.forEach(([key,value])=>value.call(this))}

也就是說利用數組循環的特性,符合正則條件的邏輯都會被執行,那就可以同時執行公共邏輯和單獨邏輯,因為正則的存在,你可以打開想象力解鎖更多的玩法,本文就不贅述了。

總結

以上所述是小編給大家介紹的JS復雜判斷的更優雅寫法代碼詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲mm色国产网站| 国产suv精品一区二区三区88区| 国产一区二区视频在线观看| 亚洲性日韩精品一区二区| 一区二区欧美日韩视频| 日韩欧美精品网站| 日韩精品中文字幕视频在线| 日韩高清电影免费观看完整| 亚洲色图欧美制服丝袜另类第一页| 国产综合福利在线| 欧美国产一区二区三区| 国产精品免费一区二区三区都可以| 久久av在线播放| 一区二区欧美在线| 国产丝袜一区视频在线观看| 日本久久久a级免费| 亚洲自拍偷拍福利| 欧美老女人性视频| 欧美激情欧美狂野欧美精品| 欧美一区二区色| 日韩精品亚洲精品| 美日韩丰满少妇在线观看| 欧美在线精品免播放器视频| 久久久精品视频在线观看| 精品国产老师黑色丝袜高跟鞋| 亚洲自拍高清视频网站| 久久久精品网站| 亚洲老板91色精品久久| 日韩有码在线播放| 亚洲国产欧美一区二区三区久久| 亚洲人成在线电影| 欧美日韩午夜视频在线观看| 久久成人18免费网站| 国产精品成人一区二区三区吃奶| 欧美性猛交xxxx黑人| 欧美日韩一区二区在线| 亚洲天堂影视av| 欧美精品videofree1080p| 亚洲人线精品午夜| 国产成人亚洲综合| 中文字幕在线国产精品| 91精品视频在线播放| 国内免费精品永久在线视频| 美女啪啪无遮挡免费久久网站| 色综合久久悠悠| 色噜噜狠狠狠综合曰曰曰| 欧美成人精品一区二区三区| 久久久精品国产亚洲| 久久久精品一区二区三区| 亚洲精品自在久久| 黄色91在线观看| 97超碰蝌蚪网人人做人人爽| 亚洲aⅴ日韩av电影在线观看| 国产精品白丝av嫩草影院| 尤物精品国产第一福利三区| 亚洲精品美女免费| 国内精品久久久久久| 2024亚洲男人天堂| 欧美剧在线观看| 亚洲最大福利网站| 亚洲国产天堂久久综合网| 亚洲免费视频在线观看| 国产精品入口夜色视频大尺度| 中文字幕免费国产精品| 日韩av一区二区在线观看| 亚洲日本中文字幕免费在线不卡| 国产精品久久久久久久久久久不卡| 欧美—级a级欧美特级ar全黄| 日韩人在线观看| 高清亚洲成在人网站天堂| 亚洲成人动漫在线播放| 久久视频国产精品免费视频在线| 青青青国产精品一区二区| 国产亚洲精品久久| 亚洲自拍偷拍视频| 2018日韩中文字幕| 久久久久久久成人| 日韩中文av在线| 国产精品美女av| 欧美精品福利视频| 青草青草久热精品视频在线观看| 国产精品羞羞答答| 欧美成人午夜免费视在线看片| 亚洲aⅴ日韩av电影在线观看| 欧美午夜精品久久久久久久| 中文字幕免费精品一区| 91香蕉电影院| 亚洲天堂第一页| 一区二区三区无码高清视频| 久久伊人免费视频| 欧美激情第1页| 亚洲日本成人女熟在线观看| 福利精品视频在线| 欧美成人精品h版在线观看| 97国产精品久久| 国产精品免费一区| 久久电影一区二区| 亚洲精品电影在线观看| 日本欧美一二三区| 欧美精品久久一区二区| 国产成人精品久久久| 神马久久桃色视频| 日本欧美在线视频| 亚洲图片制服诱惑| 日韩av免费观影| 在线视频免费一区二区| 国产欧美日韩综合精品| 欧美激情a在线| 欧美国产在线视频| 岛国av一区二区在线在线观看| 亚洲欧美日韩精品久久奇米色影视| 欧美激情欧美激情在线五月| 国产一区二区三区精品久久久| 欧美黄色片免费观看| 欧美大尺度激情区在线播放| 5566日本婷婷色中文字幕97| 亚洲精品久久久久久下一站| 精品免费在线视频| 久久久精品一区二区| 国产视频精品va久久久久久| 国产精品国产三级国产专播精品人| 另类少妇人与禽zozz0性伦| 欧美亚洲国产日本| 国产成人精彩在线视频九色| 在线观看欧美日韩| 日韩中文字幕在线| 亚洲第一中文字幕| 国产精品视频xxxx| 欧美第一淫aaasss性| 国产成人亚洲综合91| 国产精品女主播| 欧美日韩在线观看视频小说| 欧美精品中文字幕一区| 久久久久久亚洲精品不卡| 精品毛片三在线观看| 亚洲精品综合精品自拍| 色悠久久久久综合先锋影音下载| 欧美色视频日本高清在线观看| 久久久久久尹人网香蕉| 久久人人爽人人爽爽久久| 欧美成人精品在线| 亚洲美女av在线| 欧美精品www| 一区二区三区www| 国产亚洲精品久久久久久777| 国产视频精品免费播放| 中文字幕亚洲欧美日韩在线不卡| 亚洲一级黄色片| 国产精品久久久久久久美男| 久久噜噜噜精品国产亚洲综合| 一区二区三区回区在观看免费视频| 国产精品自拍偷拍| 久久久av一区| 91九色在线视频| 久久久国产在线视频| 国产亚洲精品久久久优势| 日韩一区二区av| 久久久999成人| 另类少妇人与禽zozz0性伦| 欧美亚洲免费电影| 亚洲精品视频二区| 日韩最新av在线| 久久99精品久久久久久噜噜| 国产精品视频xxxx|