首页
/
每日頭條
/
圖文
/
ifelse的改進
ifelse的改進
更新时间:2026-01-16 11:37:40

面對過多的if-else,代碼可能看起來比較冗餘,搞不好又是一張被人到處轉發的“我們項目幾百幾千行if”的圖。但是經過各種設計模式和封裝,if大大減少,但可讀性可能稍微降低了,而且比較抽象。那我們應該如何取舍呢

抛開其他因素,如果if-else過多,可讀性也許會好也可能會降低,可維護性也是或高或低;如果if-else少,代碼高度抽象,可讀性會低或者不變,可維護性可能會高也可能會低。這裡大概可能會有幾種情況

if平鋪條件單一

這種情況,if精簡不精簡,可讀性是不會變的,但是精簡程度和可維護性是正相關的。至于為什麼,看一下代碼就可以感受到了

ifelse的改進(該不該扼殺過多的if-else)1

執行語句單一

if (a === 1) { console.log('this is 1') } else if (a === 2) { console.log('this is 2') } else if (a === 3) { console.log('this is 3') } // ...還有很多 else { console.log('this is other') }

精簡代碼:

// 如果上面的if a是從1到10 console.log(`this is ${a > 0 && a < 10 ? a : 'other'}`) // 如果上面的if a是從1到5和從7-10 if ((a > 0 && a < 5) || (a > 7 && a < 10) { console.log(`this is ${a}`) } else { console.log('this is other') } // a取值靈活區間 const area = [[1,2], [5,7], [10, 11]] console.log(`${area.find(([from, to]) => { return from <= a && a <= to }) ? a : 'other'}`)

這種情況,有沒有精簡,可讀性都沒有發生變化,如果是未精簡的,寫一堆if,你還是很容易看得出幹啥。而可維護性就不一樣了,要加一個或者多個數字,那麼就要深入到某個if分支,一個個動手改,維護性低。但是,如果精簡了的話,維護性大大增加,代碼也簡短。隻需要尋找if的規律并封裝所有的case即可,最後做到“條件驅動”

一些極簡情況

有一些非常簡單的情況,可以使用&&、||、三元解決

// before if (cb) { cb() } //after cb && cb() // before if (!obj) { obj = {} } obj.a = 1 //after (obj || obj = {}).a = 1 // before if (type === true) { value = 1 } else { value = 2 } //after value = type ? 1 : 2 // before if (type === DEL) { this.delateData(id) } else { this.addData(id) } // after this[type === DEL ? 'delateData' : 'addData'](id) // or ;(type === DEL ? this.delateData : this.addData)(id) // before if (a === 1 && a === 2 && a === 10) { console.log('ok') } // after if ([1, 2, 10].includes(a)) { console.log('ok') }

條件單一、執行語句單一的情況,建議優化指數:★★★★★

執行語句複雜

if (a === 1) { console.log('this is 1') } else if (a === 2) { console.log('this is 二') } else if (a === 3) { console.log('this is three') } // ...還有很多 else { console.log('this is other') }

精簡代碼:

const map = { 1: 'this is 1', 2: 'this is 二', 3: 'this is three', // ...很多 } console.log(map[a] || 'this is other')

這種情況,和執行語句單一類似,也是可讀性不變,代碼減少了可維護性隻是略好一點。通常的解決辦法就是k-v映射了。加一個條件,就在map中加多一對k-v(由于條件處理複雜,所以條件上沒有優化空間了,必須寫出來)

這種場景,平時應該會比較常見轉為switch。如果執行語句很複雜無規律,寫k-v的缺陷就來了:一個key被迫對應一個callback函數,還會花時間斟酌傳值問題,而且代碼量也沒發生變化,此時不建議優化

if (a === 1) { console.log('this is 1') alert(a * 100); } else if (a === 2) { console.log('this is 二') document.body.innerHTML = a 1 b } // after const map = { 1: (a) => { console.log('this is 1') alert(a * 100); }, 2: (a, b) => { console.log('this is 二') document.body.innerHTML = a 1 b } } map[a](a, b) // 代碼量并沒有減少也沒有增強維護性 複制代碼

問題來了,條件單一,但處理語句有簡單的也有複雜的怎麼辦?case by case,先歸類再分情況,最終隻會剩下少量if和switch的

小結: 條件單一、執行語句複雜的情況,有規律時建議優化指數:★★★,無規律時,建議指數:★

if平鋪條件複雜

如果條件複雜,執行語句單一,那麼條件可以通過&&、||、三元來簡化,或者是平鋪if-return,問題也迎刃而解。然而,條件複雜,執行語句大概率也是複雜的。

if (a === 1) { console.log(1); } else if (arr.length === 3) { alert('this is length 3 arr'); } else if (a === 2 && b === 1) { console.log(2); console.info('haha'); } else if (a === 2) { console.log(222); document.title = 'a = 2'; } else if (arr.length) { console.error('arr is not empty'); }

都沒有規律可循,那麼就真的沒有進一步方案了。但是我們觀察一下,發現一些條件是有交集的,如a === x,我們可以把這種類型的if抽出來:

const handleA = { 1: () => { console.log(1); }, 2: () => { if (b === 1) { console.log(2); console.info('haha'); } else { console.log(222); document.title = 'a = 2'; } } } const handleArrLen = { 3: () => { alert('this is length 3 arr'); } } if (handleA[a]) { handleA[a]() } else if (arr.length) { ;(handleArrLen[arr.length] || () => { console.log(222); document.title = 'a = 2'; })() }

這樣子,可以把邏輯模塊化,增加可讀性和可維護性,但是犧牲了精簡性。

注意,上面這樣子條件模塊化了,意味着同一類的條件都會歸到一起。如果業務邏輯對if條件有嚴格要求的,比如一定要先判斷a === 1,再看看arr.length === 3,再看a === 2 && b === 1,按照這樣的順序,那就不能這樣做了

還有一種情況,就是if裡面直接調用已經封裝好的函數,沒有其他語句(其實就相當于退化為條件複雜,執行語句簡單了):

if (a === 1) { f1() } else if (arr.length === 3) { f2() } else if (a === 2 && b === 1) { f3() } else if (a === 2) { f4() } else if (arr.length) { f5() }

這種情況(前提條件,不會經常改這裡,如果是經常改,還是會吐血的),減少if後也不賴:

const index = [a === 1, arr.length === 3, a === 2 && b === 1, a === 2, arr.length].findIndex(Boolean) if (index !== -1) { [f1, f2, f3, f4, f5][index]() }

如果所有的else if都是互斥的,沒有交集,那麼換成if-return更好

if (a) { // do xx about a return } if (b) { // do xx about b return }

小結:如果條件複雜,執行語句單一,建議優化指數: ★★★★★;如果執行語句也複雜,當條件可以模塊化的且沒有順序要求,建議優化指數: ★★★★。當條件有嚴格順序要求、無規律可循,不建議強行減少if-else

if條件有嵌套

嵌套實際上就是平鋪的增強,平鋪嵌套平鋪,我們可以當作是多個if平鋪條件複雜的情況來看。例如有如下代碼,我們尋找一些規律來優化一下

if (id === 1) { console.log(1); if (type === 2) { console.log('type2'); } else { console.log('type3'); } } else if (id === 2) { console.log(2); if (type === 3) { console.log('id2 type3'); if (ext === 1) { console.log('ext1'); } } } else { console.log('other id'); }

根據id劃分:犧牲了其他因素的可讀性,但對于id的維護性增強了

const handleId = { 1: () => { console.log(1) console.log(type === 2 ? 'type2' : 'type3') }, 2: () => { console.log(2) // 這裡建議優化指數為★★,可能可讀性低,所以保持現狀也行 // eslint一開,這套涼涼,必須寫回普通if-else type === 3 && (console.log('id2 type3'), ext === 1) && console.log('ext1') } } handleId[type] ? handleId[type]() : console.log('other id')

如果此時根據type劃分,那麼難度大大增加了,這就是人人懼怕的重構了。如果後面業務邏輯,的确是以type為主導的,那重構也是早晚的事情了。所以,前期的設計以及産品邏輯,将會決定後面的維護舒服不舒服了

小結: if條件有嵌套情況,拆分if,其實就是平鋪的if嵌套平鋪的if,如果有規律可循,那麼按照前面的平鋪來減少if。如果沒有規律、也不是邏輯側重的點,那麼就不建議減少if了

總結
  • 條件簡單,執行語句單一,強烈建議減少if-else來優化,用條件驅動結果(&& ||三元或者是自己寫小邏輯)
  • 條件簡單,執行語句複雜,可保持現狀或者換成switch,如果不複雜可以使用map映射
  • 條件複雜,執行語句單一,強烈建議減少if-else來優化;如果執行語句也複雜,當條件可以模塊化的且沒有順序要求,比較建議優化。當條件有嚴格順序要求、無規律可循,不建議任何改動
  • 嵌套if,拆分為平鋪if來判斷如何優化或者不改動

作者:lhyt鍊接:https://juejin.im/post/5e86a0e56fb9a03c4a4966fb

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
武林風中日對抗賽2023赢了幾場(武林風中日對抗賽)
武林風中日對抗賽2023赢了幾場(武林風中日對抗賽)
  陳文德對戰河部大雅:雖敗猶榮!2016年12月3日,武林風中日對抗賽落下帷幕,中國勇士們奮勇拼搏,在整體實力和名氣都不如對方的情況下,最終大比分4:3戰勝對手,再次讓日本選手铩羽而歸。      武林風中日對抗賽   作為日本格鬥界的瑰寶,大雅本場與陳文德的比賽備受關注。不過賽前不管是媒體還是普通拳迷都不看好陳文德(包括小編),紛紛猜測這個95年出生名不...
2026-01-16
路易艾黎是一個怎樣的人(全球連線讓路易)
路易艾黎是一個怎樣的人(全球連線讓路易)
  新華社克賴斯特徹奇10月21日電 10月20日,在路易·艾黎先生的故鄉——新西蘭南島最大城市克賴斯特徹奇,鮮花盛開,春光明媚。市政廳内,中新兩國人士聚集一堂,熱議繼續傳承和弘揚路易·艾黎精神,共同為兩國關系開創更加美好的未來。   路易·艾黎自1927年起在華工作生活60年,與中國人民風雨同舟,是工業合作社運動發起者,山丹培黎學校創辦者,将畢生獻給中國人...
2026-01-16
冬季釣草魚用什麼釣餌(冬天如何釣草魚)
冬季釣草魚用什麼釣餌(冬天如何釣草魚)
  莫言草木委冬雪。會應蘇息遇陽春。草魚是典型的草食性魚類,喜熱怕冷,當氣溫較低時,草魚就會躲到深水區,停止覓食活動。所以,到了冬季以後,草魚會變得很難釣,北方的寒冷天氣不适合釣草魚了。但是,在南方一些比較暖和的地區,依然可以釣草魚。但是,并不是任何時候都可以釣到草魚,需要把握好出釣時間,選擇正确的釣位,使用好用的魚餌,才能釣到草魚。下面,我來講下冬天釣草魚...
2026-01-16
何冰嬌奪賽季第四冠了嗎(何冰嬌2022賽季戰績)
何冰嬌奪賽季第四冠了嗎(何冰嬌2022賽季戰績)
  随着何冰嬌不敵戴資穎無緣總決賽決賽,結束本賽季的所有比賽。   2022德國公開賽(2022.3.8-2022.3.13)冠軍   1/16決賽 何冰嬌2-0(22-20,21-17)大堀彩   1/8決賽 何冰嬌2-0(21-17,21-11)山口茜   1/4決賽 何冰嬌0-0因達農(退賽)   半決賽 何冰嬌2-0(21-12,21-15)安洗瑩 ...
2026-01-16
特斯拉自動駕駛被曝重大漏洞(特斯拉聯合創始人)
特斯拉自動駕駛被曝重大漏洞(特斯拉聯合創始人)
  編者按:去年 12 月,Insider 采訪了埃伯哈德,并整理成了這份報道。馬丁·埃伯哈德曾被稱為「Mr. Tesla.」,但現在他把自己叫做「退休的企業家」。這位特斯拉聯合創始人談論了從他的初創公司早期到電動汽車未來的方方面面,當然也包括他和馬斯克的一些「私人恩怨」。   很多帶有傳奇色彩的企業家背後都有很多傳奇故事,更别說每天都能引起半個地球熱議的馬...
2026-01-16
Copyright 2023-2026 - www.tftnews.com All Rights Reserved