<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          通過刪除“ if-else”語句來清理代碼

          共 6532字,需瀏覽 14分鐘

           ·

          2020-07-14 03:16

          72989ebbb4f2a6eafce41ab702224393.webp


          在編寫JS代碼時,經(jīng)常會遇到復(fù)雜邏輯判斷的情況。通常,可以使用if / else或switch來執(zhí)行多個條件判斷,但是會出現(xiàn)問題:隨著邏輯復(fù)雜性的增加,if / else和switch中的代碼將變得越來越腫。本文將帶您嘗試編寫更優(yōu)雅的判斷邏輯。例如,讓我們看一段代碼:
          /** * Button click event * @param {number} status  *    Activity status: 1 in progress, 2 in failure, 3 out of stock, 4 in success, 5 system cancelled */const onButtonClick = (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')  }}
          您可以在代碼中看到此按鈕的單擊邏輯:根據(jù)不同的活動狀態(tài)執(zhí)行兩件事,發(fā)送日志隱藏點(diǎn)并跳轉(zhuǎn)到相應(yīng)的頁面,您可以通過swtich輕松地提出對此代碼的重寫。
          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清楚得多,細(xì)心的讀者可能還會發(fā)現(xiàn)一個小技巧:情況2和情況3的邏輯相同,我們可以保存執(zhí)行語句并中斷,情況2將按照情況3的邏輯自動執(zhí)行。但是有一種更簡單的編寫方法。
          const actions = {  '1': ['processing','IndexPage'],  '2': ['fail','FailPage'],  '3': ['fail','FailPage'],  '4': ['success','SuccessPage'],  '5': ['cancel','CancelPage'],  'default': ['other','Index'],}
          const onButtonClick = (status)=>{ let action = actions[status] || actions['default'], logName = action[0], pageName = action[1] sendLog(logName) jumpTo(pageName)}
          上面的代碼看上去確實(shí)更簡潔,這種方法的聰明之處在于它使用判斷條件作為對象的屬性名稱,并使用處理邏輯作為對象的屬性值。當(dāng)單擊按鈕時,此方法特別適用于一元條件判斷的情況,該條件通過對象屬性查找進(jìn)行邏輯判斷。很好,但是還有另一種編碼方式嗎?
          是!
          const actions = new Map([  [1, ['processing','IndexPage']],  [2, ['fail','FailPage']],  [3, ['fail','FailPage']],  [4, ['success','SuccessPage']],  [5, ['cancel','CancelPage']],  ['default', ['other','Index']]])
          const onButtonClick = (status)=>{ let action = actions.get(status) || actions.get('default') sendLog(action[0]) jumpTo(action[1])}
          使用Map代替Object有很多優(yōu)點(diǎn),我們將在后面討論。Map對象和普通對象之間有什么區(qū)別?
          • 一個對象通常有自己的原型,所以一個對象總是有一個“原型”鍵,除非我們使用Object.create(null)創(chuàng)建一個沒有原型的對象;

          • 對象的鍵只能是字符串或符號,但是Map的鍵可以是任何值。

          • 您可以通過使用size屬性輕松獲得Map中的鍵/值對數(shù)量,而對象中的鍵/值對數(shù)量只能手動確認(rèn)。

          現(xiàn)在,讓我們升級問題的難度。單擊按鈕時,不僅需要判斷狀態(tài),還需要判斷用戶的身份:
          /** * Button click event * @param {number} status  *    Activity status: 1 in progress, 2 in failure, 3 out of stock, 4 in success, 5 system cancelled * * @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    }  }}
          從上面的示例中可以看到,當(dāng)邏輯升級為雙重判斷時,判斷增加了一倍,代碼也增加了一倍。我們?nèi)绾尾拍芨逦鼐帉懘a?這是一個解決方案:
          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*/}],])
          const onButtonClick = (identity,status)=>{ let action = actions.get(`${identity}_${status}`) || actions.get('default') action.call(this)}
          以上代碼的核心邏輯是:將兩個判斷條件拼接成一個字符串作為Map的鍵,然后在查詢過程中直接搜索對應(yīng)字符串的值。當(dāng)然,我們也可以在這里將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)}
          如果讀者發(fā)現(xiàn)將查詢拼寫為字符串有點(diǎn)笨拙,那么還有另一種解決方案,即使用Map對象作為鍵:
          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))}
          加點(diǎn)難度。如果在來賓情況下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))}
          這足以滿足日常需求,但嚴(yán)重的是,將函數(shù)A覆蓋四次仍然有點(diǎn)煩人。如果事情變得非常復(fù)雜,例如身份具有3個狀態(tài),狀態(tài)具有10個狀態(tài),則需要定義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而不是Object的優(yōu)勢更加明顯,因?yàn)镽egular類型可以用作鍵。如果要求變?yōu)椋核衼碣e情況都需要發(fā)送日志掩埋點(diǎn),而不同狀態(tài)情況需要單獨(dú)的邏輯處理,那么我們可以編寫如下:
          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))}
          也就是說,利用數(shù)組循環(huán)的屬性,將執(zhí)行任何符合常規(guī)條件的邏輯,從而可以同時執(zhí)行公共邏輯和單個邏輯。結(jié)論本文教了您八種編寫邏輯判斷的方法,包括:
          1. if/else

          2. switch

          3. 一元判斷:存儲在Object中

          4. 一元判斷:保存到Map

          5. 多重判斷:將條件連接成字符串并將其保存在Object中

          6. 多重判斷:將條件連接成字符串并將其存儲在Map中

          7. 多重判斷:將條件另存為Map中的對象

          8. 多重判斷:將條件另存為Map中的正則表達(dá)式

          對于本文而言,如此之多,也許您的未來將充滿了if / else或switch。


          瀏覽 13
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日噜狠狠色综合 | 国产在线拍揄自揄拍无码视频 | 欧洲性爱精品视频 | 色情按摩做爰A片91 | 少妇后入网址 |