自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何優(yōu)化JavaScript中的復(fù)雜判斷?

開發(fā) 前端
我們在寫JavaScript代碼的時(shí)候,經(jīng)常會遇到邏輯判斷比較復(fù)雜的情況,通常我們可以使用if/else或者switch來實(shí)現(xiàn)多個(gè)條件判斷。

我們在寫JavaScript代碼的時(shí)候,經(jīng)常會遇到邏輯判斷比較復(fù)雜的情況,通常我們可以使用if/else或者switch來實(shí)現(xiàn)多個(gè)條件判斷。

但是有一個(gè)問題,隨著邏輯復(fù)雜度的增加,代碼中的if/else/switch會越來越臃腫,難以理解。那么如何才能寫出更優(yōu)雅的判斷邏輯呢?

示例:

/**
 * Button click event
 * @param {number} status:1 2 3 4 5
 */
const onButtonClick = (status)=>{
  if(status == 1){
    jumpTo('IndexPage')
  }else if(status == 2){
    jumpTo('FailPage')
  }else if(status == 3){
    jumpTo('FailPage')
  }else if(status == 4){
    jumpTo('SuccessPage')
  }else if(status == 5){
    jumpTo('CancelPage')
  }else {
    jumpTo('Index')
  }
}

從代碼中我們可以看到這個(gè)按鈕的點(diǎn)擊邏輯:根據(jù)不同的活動(dòng)狀態(tài),做兩件事,發(fā)送日志事件,跳轉(zhuǎn)到對應(yīng)頁面。大家很容易就提出使用 switch 進(jìn)行代碼重寫方案:

const onButtonClick = (status)=>{
  switch (status){
    case 1:
      console.log('IndexPage')
      break
    case 2:
    case 3:
      jumpTo('FailPage')
      break  
    case 4:
      jumpTo('SuccessPage')
      break
    case 5:
      jumpTo('CancelPage')
      break
    default:
      jumpTo('Index')
      break
  }
}

這樣看起來比用 if/else 清晰多了,你還發(fā)現(xiàn)了一個(gè)小技巧:當(dāng) case 2 和 case 3 的邏輯相同時(shí),可以省略執(zhí)行語句和 break,這樣 case 2 的邏輯就會自動(dòng)執(zhí)行 case 3 的邏輯。

持續(xù)優(yōu)化:

const actions = {
  '1': ['IndexPage'],
  '2': ['FailPage'],
  '3': ['FailPage'],
  '4': ['SuccessPage'],
  '5': ['CancelPage'],
  'default': ['Index'],
}
const onButtonClick = (status)=>{
  let action = actions[status] || actions['default'],
  jumpTo(action[0])
}

現(xiàn)在代碼確實(shí)看起來干凈多了,這個(gè)方法的巧妙之處在于:把判定條件作為對象的屬性名,把處理邏輯作為對象的屬性值,點(diǎn)擊按鈕時(shí)通過查找對象屬性進(jìn)行邏輯判斷,這種寫法特別適合一元條件判斷。

還有其他寫法嗎?用map:

const actions = new Map([
  [1, ['IndexPage']],
  [2, ['FailPage']],
  [3, ['FailPage']],
  [4, ['SuccessPage']],
  [5, ['CancelPage']],
  ['default', ['Index']]
])
const onButtonClick = (status)=>{
  let action = actions.get(status) || actions.get('default')
  jumpTo(action[0])
}

這樣寫的話,就用到了ES6中的Map對象,是不是感覺順暢多了?Map對象和Object有什么區(qū)別?

  • 對象通常有自己的原型,所以對象總有一個(gè)原型鍵。
  • 對象的鍵只能是字符串或者Symbol,而Map的鍵可以是任意值。

Map中鍵值對的數(shù)量可以通過size屬性輕松獲取,而對象中鍵值對的數(shù)量只能手動(dòng)確認(rèn)。

復(fù)雜一點(diǎn)的話,再加一層判斷如何?

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)你的邏輯升級為二元判斷的時(shí)候,判斷量和代碼量都會翻倍,這時(shí)候怎么才能寫得更干凈呢?

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)
}

上述代碼的核心邏輯是:將兩個(gè)條件拼接成一個(gè)字符串,以拼接后的條件字符串為鍵,以處理函數(shù)為值,通過 Map 對象查找并執(zhí)行。這種方法在做多條件判斷的時(shí)候特別有用。

當(dāng)然,使用 Object 實(shí)現(xiàn)上述代碼也是類似的:

const actions = {
  'guest_1':()=>{/*do sth*/},
  'guest_2':()=>{/*do sth*/},
  //....
}


const onButtonClick = (identity,status)=>{
  let action = actions[`${identity}_${status}`] || actions['default']
  action.call(this)
}

如果把查詢條件拼接成字符串感覺有點(diǎn)別扭的話,還有另外一個(gè)解決辦法,就是使用一個(gè)以 Object 對象為鍵的 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))
}

這里我們也可以看出Map和Object的區(qū)別,Map可以使用任意類型的數(shù)據(jù)作為key。

我們再增加一點(diǎn)難度,假設(shè)一個(gè)客人的情況,狀態(tài)1-4的處理邏輯都一樣,我們該如何處理呢?最壞的情況是這樣的:

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))
}

這樣寫已經(jīng)可以滿足日常需求了。

不過說真的,重寫 functionA 四次還是有點(diǎn)麻煩的。如果情況變得特別復(fù)雜,比如,身份有三種狀態(tài),狀態(tài)有十種狀態(tài),那么就需要定義 30 個(gè)處理邏輯。

而且往往這些邏輯很多都是相同的,這看起來有點(diǎn)讓人難以接受。那么可以這樣實(shí)現(xiàn):

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 的優(yōu)勢就更加凸顯了,它允許使用正則類型作為鍵,這帶來了無限可能。假設(shè)需求發(fā)生了變化,每個(gè)客人場景都需要發(fā)送日志事件,不同的狀態(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)的特性,滿足正則表達(dá)式條件的邏輯就會被執(zhí)行,這樣就可以同時(shí)執(zhí)行通用邏輯和個(gè)別邏輯。有了正則表達(dá)式的存在,你可以發(fā)揮你的想象力,解鎖更多的可能性。

責(zé)任編輯:華軒 來源: web前端開發(fā)
相關(guān)推薦

2024-10-07 12:23:03

字符串Map對象

2025-04-27 03:44:00

JavaScript代碼函數(shù)

2025-04-25 08:50:00

JavaScript代碼開發(fā)

2020-10-22 14:00:31

JavaScript數(shù)字變量

2020-10-22 08:06:05

JavaScrip語言類型

2009-06-10 22:00:57

JavaScript腳

2009-06-11 17:15:23

JavaScript性

2022-09-12 23:53:53

JavaScript條件判斷開發(fā)

2016-08-03 17:23:47

javascripthtml前端

2011-05-27 16:00:10

DB2

2022-09-04 15:40:39

JavaScrip狀態(tài)模式軟件

2013-08-01 13:18:41

代碼

2020-08-23 11:32:21

JavaScript開發(fā)技術(shù)

2011-05-25 10:46:39

Javascript

2025-01-07 15:20:24

2024-06-14 08:54:54

2011-07-13 09:46:23

javaScript

2012-03-12 09:33:04

JavaScript

2020-11-27 10:25:36

物聯(lián)網(wǎng)設(shè)備軟件

2022-05-18 08:00:00

JavaScriptFetch數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號