首页
/
每日頭條
/
圖文
/
ifelse的改進
ifelse的改進
更新时间:2026-03-01 11:34:20

面對過多的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
推荐阅读
和田玉羊脂玉怎麼識别真假的方法(和田玉的謠言一)
和田玉羊脂玉怎麼識别真假的方法(和田玉的謠言一)
  一說到和田玉,大家想到最多的詞語便是“羊脂玉”,好多商家也說自己的玉是羊脂玉,那到底什麼是羊脂玉,真的很稀缺珍貴嗎?   關于“羊脂玉”,大家有許多不了解,市場上也有很多羊脂玉的謠言,下面我用5句話給大家說清楚“羊脂玉”的前世今生。   1、在三國時代,曹丕曾在《與鐘繇謝玉玦書》中曰:“竊見玉書,稱美玉白如截肪,黑譬純漆,赤拟雞冠,黃侔蒸栗” 這是史料中...
2026-03-01
鹿鼎記和天龍八部相同演員(天龍八部鹿鼎記之後她光芒不再)
鹿鼎記和天龍八部相同演員(天龍八部鹿鼎記之後她光芒不再)
     《知否知否應是綠肥紅瘦》收官之後,當下熱播的各部古裝劇平分秋色,最近話題度比較高的,除了《東宮》和《獨孤皇後》以外,大概就是劇名相當惹眼的《招搖》了。      大概是因為與才播出不久、由楊幂主演的古裝玄幻劇《扶搖》劇名高度重合,網友們對這部劇的吐槽和議論不斷。不過從這部劇中,卻有另外一個值得注意卻被大多數網友忽略的點,那就是其中獨孤修的扮演者竟然...
2026-03-01
一拳十大最強s級英雄(新英雄協會12位S級解析)
一拳十大最強s級英雄(新英雄協會12位S級解析)
  關注ONE老師原作版一拳超人漫畫的小夥伴,想必對新英雄協會NEO并不陌生。作為英雄協會的對家,它不僅網羅了脫離英雄協會的原S級英雄,更有一些已出場人物的關系者包括在其中。本篇拾溜就來介紹将成為新英雄協會的12位S級英雄的強力角色,内容僅供參考。      殺手艾(殺し屋エー)   成為英雄之前,他是特A級懸賞犯,雖然相比S級的索尼克低一級,他仍擁有對于擊...
2026-03-01
德語日常會話用語(德語學習我很性感)
德語日常會話用語(德語學習我很性感)
  Emil:Wo warst du? (你去哪了?)   Ich bin in die Toilette gegangen.:小明   Emil:Was zur Hölle?! (WTF?)   其實小明想說:Ich bin auf die Toilette gegangen. ——我剛去廁所了。。。   但是表達的實際意思卻是:我剛去了馬桶裡。     ...
2026-03-01
那些年看過的超好看的泰劇(這些甜到令人心動的泰劇你看過嗎)
那些年看過的超好看的泰劇(這些甜到令人心動的泰劇你看過嗎)
  最近飯哥發現了一部高顔值的泰劇《逐月之月》,這部劇剛開始光看劇照就被男主的顔值迷得不要不要的~雙向暗戀的設定簡直太戳萌點了,現在隻更新到第二集,等待更新日子太難熬。同時呢,飯哥也整理了幾部同樣甜到令人心動的泰劇,和大家一起分享。   《逐月之月》   《逐月之月》根據泰國暢銷小說《Two Moons》改編,主要講述了一個理工學院院草暗戀校草學長的故事,由...
2026-03-01
Copyright 2023-2026 - www.tftnews.com All Rights Reserved