我們?cè)诰帉?JS 代碼時(shí),經(jīng)常會(huì)遇到邏輯判斷復(fù)雜的情況。一般情況下,可以用 if/else 或 switch
          來實(shí)現(xiàn)多個(gè)條件判斷,但會(huì)出現(xiàn)一個(gè)問題:隨著邏輯復(fù)雜度的增加,代碼中的 if/else 和 switch 會(huì)越來越臃腫。本文將帶你嘗試寫出更優(yōu)雅的判斷邏輯。

          比如說下面這樣一段代碼:
          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') } }
          你可以在代碼中看到這個(gè)按鈕的點(diǎn)擊邏輯。根據(jù)活動(dòng)狀態(tài)的不同做兩件事,發(fā)送日志埋點(diǎn)并跳轉(zhuǎn)到相應(yīng)的頁(yè)面。很容易想到這段代碼可以用 switch 重寫如下:
          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 層次結(jié)構(gòu)更清晰一些,細(xì)心的讀者可能也發(fā)現(xiàn)了一個(gè)小竅門:case 2 和 case 3
          的邏輯一樣時(shí),可以把前面的邏輯處理代碼省略,case 2 會(huì)自動(dòng)執(zhí)行與 case 3 的邏輯。

          不過,還有一個(gè)更簡(jiǎn)單的寫法:
          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í)比較干凈,這種方法的巧妙之處在于,它把判斷條件作為對(duì)象的屬性名,把處理邏輯作為對(duì)象的屬性值。在點(diǎn)擊按鈕的時(shí)候,這種方法特別適用于單項(xiàng)條件判斷的情況,即通過對(duì)象屬性查找的方式進(jìn)行邏輯判斷。

          這個(gè)方法很好,但是有沒有其他的方法來編碼呢?有的!
          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 對(duì)象和普通對(duì)象有的區(qū)別是:

          * 一個(gè)對(duì)象通常有自己的原型,所以一個(gè)對(duì)象總是有一個(gè)“prototype”鍵
          * 對(duì)象的鍵只能是一個(gè)字符串或符號(hào),但 Map 的鍵可以是任何值
          * 你可以通過使用 size 屬性很容易得到 Map 中的鍵值對(duì)的數(shù)量,而一個(gè)對(duì)象中的鍵值對(duì)數(shù)量不能直接獲取
          現(xiàn)在我們來升級(jí)一下這個(gè)問題的難度。點(diǎn)擊按鈕時(shí),不僅要判斷狀態(tài),還要判斷用戶的身份。
          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)你的邏輯升級(jí)到雙重判斷的時(shí)候,你的判斷力就會(huì)加倍,你的代碼就會(huì)加倍。

          如何才能讓代碼更干凈利落呢?

          這里有一個(gè)解決方案。
          const actions = new Map([ ['guest_1', () => {}], ['guest_2', () => {}],
          ['guest_3', () => {}], ['guest_4', () => {}], ['guest_5', () => {}],
          ['master_1', () => {}], ['master_2', () => {}], ['master_3', () => {}],
          ['master_4', () => {}], ['master_5', () => {}], ['default', () => {}], ]) const
          onButtonClick = (identity, status) => { let action =
          actions.get(`${identity}_${status}`) || actions.get('default')
          action.call(this) }
          上述代碼的核心邏輯是。將兩個(gè)判斷條件拼接成一個(gè)字符串作為 Map 的鍵,然后在查詢時(shí)直接查詢對(duì)應(yīng)字符串的值。當(dāng)然,我們也可以在這里把 Map 改成
          Object。
          const actions = { guest_1: () => {}, guest_2: () => {}, //.... } const
          onButtonClick = (identity, status) => { let action =
          actions[`${identity}_${status}`] || actions['default'] action.call(this) }
          如果讀者覺得把查詢拼成一個(gè)字符串有點(diǎn)尷尬,還有另一個(gè)解決辦法,那就是用一個(gè) Map 對(duì)象作為 key。
          const actions = new Map([ [{ identity: 'guest', status: 1 }, () => {}], [{
          identity: 'guest', status: 2 }, () => {}], //... ]) const onButtonClick =
          (identity, status) => { let action = [...actions].filter(([key, value]) =>
          key.identity == identity && key.status == status) action.forEach(([key, value])
          => value.call(this)) }
          這里你也可以看到 Map 和普通對(duì)象的區(qū)別,其中 Map 可以用任何類型的數(shù)據(jù)作為鍵?,F(xiàn)在讓我們把它的難度再提高一點(diǎn)。如果對(duì)于 guest 身份來說,狀態(tài)
          1-4 的處理邏輯是一樣的呢?

          最壞的情況是這樣的(代碼大量重復(fù)):
          const actions = new Map([ [{ identity: 'guest', status: 1 }, () => {}], [{
          identity: 'guest', status: 2 }, () => {}], [{ identity: 'guest', status: 3 },
          () => {}], [{ identity: 'guest', status: 4 }, () => {}], [{ identity: 'guest',
          status: 5 }, () => {}], //... ])
          更好的方法是把處理邏輯函數(shù)分離出來:
          const actions = () => { const functionA = () => {} const functionB = () => {}
          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)) }
          這對(duì)于日常需求來說已經(jīng)足夠了,但是說真的,函數(shù) A 被引用了 4 次,還是有點(diǎn)煩人。

          如果事情真的變得很復(fù)雜,比如身份有 3 種,狀態(tài)有 10 種,你需要定義 30 個(gè)處理邏輯,其中很多處理邏輯都是一樣的,這似乎讓人無(wú)法接受。

          而你可以這樣做:
          const actions = () => { const functionA = () => {} // 邏輯處理 A const functionB =
          () => {} // 邏輯處理 B 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)) }
          這時(shí)使用 Map 而不是 Object 的優(yōu)勢(shì)比較明顯,因?yàn)榭梢杂谜齽t式作為鍵。

          如果需求變成:所有的對(duì) guest 操作都需要發(fā)送一個(gè)日志埋點(diǎn),不同狀態(tài)的 guest 可能有不同的邏輯處理,那么我們可以寫成如下:
          const actions = () => { const functionA = () => {} // 邏輯處理 A const functionB =
          () => {} // 邏輯處理 B const functionC = () => {} // 發(fā)送日志 C 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)) }
          這樣一來,公共邏輯和單個(gè)邏輯可以同時(shí)執(zhí)行。

          總結(jié)

          本文講到了八種 JS 邏輯判斷的寫法,包括:

          * if/else
          * switch
          * 單一判斷:存儲(chǔ)在 Object 中
          * 單一判斷:存儲(chǔ)在 Map 對(duì)象中
          * 多重判斷:將條件串聯(lián)成一個(gè)字符串,存儲(chǔ)在 Object 中
          * 多重判斷:將條件連成一個(gè)字符串,存儲(chǔ)在 Map 對(duì)象中
          * 多重判斷:把條件作為對(duì)象存儲(chǔ)在 Map 中
          * 多重判斷:把條件寫成正則式存儲(chǔ)在 Map 中
          今天就分享到這里,愿你今后的編碼生活不僅僅只有 if/else 或 switch。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                免费的黄视频 | 精品无码国产成人网站尤物app | 小受被打开双腿狠狠灌满 | 国产一级淫片a片奶网站 | 亚洲熟妇无码 |