首页
/
每日頭條
/
圖文
/
ifelse的改進
ifelse的改進
更新时间:2025-07-12 14:11:44

面對過多的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
推荐阅读
如何讓自己變得優秀的幾個小竅門(如何讓自己變得更加優秀)
如何讓自己變得優秀的幾個小竅門(如何讓自己變得更加優秀)
  要想優秀,首先要敢于伸手去夠那些更高的果子。很多時候把手伸出去、把腳踮起來,已經戰勝了90%的人。   如何讓自己變得更加優秀?   這裡準備了16條法則,希望對你有所幫助。   1   對自己的行為負責   當自己所處的境遇不好的時候,更要多看看自己身上的原因。   有一句話說,你現在在哪兒是你過去兩年來的選擇決定的;你兩年後在哪兒是你接下去兩年中的選...
2025-07-12
越巫自取滅亡的原因(先秦典籍中的火葬探析
越巫自取滅亡的原因(先秦典籍中的火葬探析
  先秦典籍中的火葬探析   姚海濤   (青島理工大學琴島學院,山東青島 266106)   摘要:火葬習俗古已有之。先秦典籍中保留了有關火葬的大量文本證據。大體言之,《周易》中的離卦與火葬有着密切關系,作為刑法處罰方式而存在,主要指向不孝子這一群體。而《墨子》《呂氏春秋》《荀子》《列子》中記錄的火葬主要是作為氐、羌以及儀渠民族的喪葬形制。透過這些現象側面...
2025-07-12
人過四十後看淡簡單的生活(人到四十以後隻有)
人過四十後看淡簡單的生活(人到四十以後隻有)
     塵世間太多的情感,總是虛無缥缈,如水中之月,霧裡看花,追不到,摸不着,守不住,又放不下。   深陷紅塵的我們,常常會迷失在塵世之中,行色匆匆的專注趕路,卻忘了自己,也忘了看看沿途的風景。   一晃,已過而立之年,步入了不惑之年,此時,沉穩,從容才是大境界。   俗話說:四十不惑。過了四十,哪些事情應該堅持,哪些事情應該扔掉,心裡應該有數了。   人...
2025-07-12
如何走出人生規劃的誤區(自控力和對周圍的規劃能力)
如何走出人生規劃的誤區(自控力和對周圍的規劃能力)
     今天我們接着學《弟子規》,一晃馬上要學完了,也就還有那麼兩三天了,昨天我們講了“墨磨偏,心不端,字不敬,心先病。”   我覺得我們現在大家推崇的匠人精神應該是最佳體現了,那種凝神靜氣,然後把手中的小事認真的做好,那麼在大方向上是為大家忘記名利,把手中的事做得紮紮實實,這就是道的具體體現。   今天我們學習的這句話叫“列典籍,有定處,讀看畢,還原處。...
2025-07-12
五年級數學簡便運算題20道有答案(五年級數學簡便運算方法)
五年級數學簡便運算題20道有答案(五年級數學簡便運算方法)
     在孩子的小學數學中,數學的學習,基本内容包含:對數的認識,數的運算,圖形的認識以及運算,還有就是對數的應用,這幾個部分,但是在從1年級到6年級一直學習的一項内容,而且貫穿始終的,那就是簡便運算。   在整數範圍、小數範圍、分數範圍内都會作為一個内容重複出現,而這個内容也正是小學數學中的一個難點。   一、提取公因式   這個方法實際上是運用了乘法分...
2025-07-12
Copyright 2023-2025 - www.tftnews.com All Rights Reserved