最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS 邏輯判斷不要只知道用 if-else 和 switch條件判斷(小技巧)

 更新時間:2020年05月27日 15:31:48   作者:前端小蜜蜂  
這篇文章主要介紹了JS 邏輯判斷不要只知道用 if-else 和 switch,在一些邏輯復(fù)雜度的增加,代碼中的 if/else 和 switch 會越來越臃腫。本文將帶你嘗試寫出更優(yōu)雅的判斷邏輯,需要的朋友可以參考下

我們在編寫 JS 代碼時,經(jīng)常會遇到邏輯判斷復(fù)雜的情況。一般情況下,可以用 if/else 或 switch 來實(shí)現(xiàn)多個條件判斷,但會出現(xiàn)一個問題:隨著邏輯復(fù)雜度的增加,代碼中的 if/else 和 switch 會越來越臃腫。本文將帶你嘗試寫出更優(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')
 }
}

你可以在代碼中看到這個按鈕的點(diǎn)擊邏輯。根據(jù)活動狀態(tài)的不同做兩件事,發(fā)送日志埋點(diǎn)并跳轉(zhuǎn)到相應(yīng)的頁面。很容易想到這段代碼可以用 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)了一個小竅門:case 2 和 case 3 的邏輯一樣時,可以把前面的邏輯處理代碼省略,case 2 會自動執(zhí)行與 case 3 的邏輯。

不過,還有一個更簡單的寫法:

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í)比較干凈,這種方法的巧妙之處在于,它把判斷條件作為對象的屬性名,把處理邏輯作為對象的屬性值。在點(diǎn)擊按鈕的時候,這種方法特別適用于單項(xià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ū)別是:

  • 一個對象通常有自己的原型,所以一個對象總是有一個“prototype”鍵
  • 對象的鍵只能是一個字符串或符號,但 Map 的鍵可以是任何值
  • 你可以通過使用 size 屬性很容易得到 Map 中的鍵值對的數(shù)量,而一個對象中的鍵值對數(shù)量不能直接獲取

現(xiàn)在我們來升級一下這個問題的難度。點(diǎn)擊按鈕時,不僅要判斷狀態(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)你的邏輯升級到雙重判斷的時候,你的判斷力就會加倍,你的代碼就會加倍。

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

這里有一個解決方案。

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

上述代碼的核心邏輯是。將兩個判斷條件拼接成一個字符串作為 Map 的鍵,然后在查詢時直接查詢對應(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)
}

如果讀者覺得把查詢拼成一個字符串有點(diǎn)尷尬,還有另一個解決辦法,那就是用一個 Map 對象作為 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 和普通對象的區(qū)別,其中 Map 可以用任何類型的數(shù)據(jù)作為鍵?,F(xiàn)在讓我們把它的難度再提高一點(diǎn)。如果對于 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))
}

這對于日常需求來說已經(jīng)足夠了,但是說真的,函數(shù) A 被引用了 4 次,還是有點(diǎn)煩人。

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

而你可以這樣做:

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

這時使用 Map 而不是 Object 的優(yōu)勢比較明顯,因?yàn)榭梢杂谜齽t式作為鍵。

如果需求變成:所有的對 guest 操作都需要發(fā)送一個日志埋點(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))
}

這樣一來,公共邏輯和單個邏輯可以同時執(zhí)行。

總結(jié)

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

  1. if/else
  2. switch
  3. 單一判斷:存儲在 Object 中
  4. 單一判斷:存儲在 Map 對象中
  5. 多重判斷:將條件串聯(lián)成一個字符串,存儲在 Object 中
  6. 多重判斷:將條件連成一個字符串,存儲在 Map 對象中
  7. 多重判斷:把條件作為對象存儲在 Map 中
  8. 多重判斷:把條件寫成正則式存儲在 Map 中

到此這篇關(guān)于JS 邏輯判斷不要只知道用 if-else 和 switch條件判斷的文章就介紹到這了,更多相關(guān)js 邏輯判斷if else switch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • webpack+vue-cil中proxyTable處理跨域的方法

    webpack+vue-cil中proxyTable處理跨域的方法

    這篇文章主要介紹了webpack+vue-cil中proxyTable處理跨域的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • 基于JS+HTML實(shí)現(xiàn)彈窗提示是否確認(rèn)提交功能

    基于JS+HTML實(shí)現(xiàn)彈窗提示是否確認(rèn)提交功能

    這篇文章主要介紹了基于JS+HTML實(shí)現(xiàn)彈窗提示是否確認(rèn)提交功能,需要的朋友可以參考下
    2020-06-06
  • 超鏈接怎么正確調(diào)用javascript函數(shù)

    超鏈接怎么正確調(diào)用javascript函數(shù)

    本文介紹使用超鏈接調(diào)用javasript函數(shù)且不會影響GIF圖片動畫的方法,有遇到相同問題的小伙伴可以參考一下。
    2016-05-05
  • js for循環(huán),為什么一定要加var定義i變量

    js for循環(huán),為什么一定要加var定義i變量

    我知道,有些人(譬如之前的我)寫js的for循環(huán)時,都不習(xí)慣加上var,這當(dāng)然是語法允許的。
    2010-06-06
  • 淺談js中的變量名和函數(shù)名重名

    淺談js中的變量名和函數(shù)名重名

    下面小編就為大家?guī)硪黄獪\談js中的變量名和函數(shù)名重名。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 關(guān)于圖片的預(yù)加載過程中隱藏未知的

    關(guān)于圖片的預(yù)加載過程中隱藏未知的

    相信大家都看到過ie下的內(nèi)存泄漏模式的文章,其中有一個模式就是循環(huán)引用,而閉包就有保存外部運(yùn)行環(huán)境的能力(依賴于作用域鏈的實(shí)現(xiàn)),所以img.onload這個函數(shù)內(nèi)部又保存了對img的引用,這樣就形成了循環(huán)引用,導(dǎo)致內(nèi)存泄漏
    2012-12-12
  • 用微信小程序?qū)崿F(xiàn)計算器功能

    用微信小程序?qū)崿F(xiàn)計算器功能

    這篇文章主要為大家詳細(xì)介紹了用微信小程序?qū)崿F(xiàn)計算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • uniapp?@click事件冒泡問題解決示例

    uniapp?@click事件冒泡問題解決示例

    這篇文章主要為大家介紹了uniapp?@click事件冒泡問題解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • JavaScript學(xué)習(xí)筆記之DOM基礎(chǔ)操作實(shí)例小結(jié)

    JavaScript學(xué)習(xí)筆記之DOM基礎(chǔ)操作實(shí)例小結(jié)

    這篇文章主要介紹了JavaScript學(xué)習(xí)筆記之DOM基礎(chǔ)操作,結(jié)合實(shí)例形式總結(jié)分析了javascript針對dom元素節(jié)點(diǎn)、屬性的相關(guān)獲取、設(shè)置等操作技巧,需要的朋友可以參考下
    2019-01-01
  • JSON字符串和對象相互轉(zhuǎn)換實(shí)例分析

    JSON字符串和對象相互轉(zhuǎn)換實(shí)例分析

    這篇文章主要介紹了JSON字符串和對象相互轉(zhuǎn)換的方法,結(jié)合實(shí)例形式分析了json格式數(shù)據(jù)的轉(zhuǎn)換方法,涉及javascript正則與字符串操作的相關(guān)技巧,需要的朋友可以參考下
    2016-06-06

最新評論

卓资县| 阿拉善左旗| 通州市| 柳江县| 北宁市| 福清市| 义乌市| 藁城市| 井研县| 南召县| 扎赉特旗| 合肥市| 常山县| 冀州市| 万州区| 岳阳市| 巴马| 天全县| 安庆市| 沛县| 沛县| 土默特左旗| 汪清县| 文山县| 云和县| 南充市| 闻喜县| 团风县| 丘北县| 烟台市| 维西| 潍坊市| 旌德县| 隆尧县| 大方县| 德阳市| 贵港市| 从化市| 勃利县| 车险| 娱乐|