優化 js中的if else-if 語句 過多的情況


像這種代碼就很打腦殼~

// 貸款申請操作的處理
function check() {
  // 是否輸入正確用戶名
  if (this.checkUsername(this.username)) {
    // 是否輸入正確身份證號
    if (this.checkIdCard(this.idCard)) {
      // 請輸入正確的電話號碼
      if (this.checkTel(this.tel)) {
        // 擔保人是本人
        if (this.dbr === '擔保人是本人') {
          // 是否存在身份證正面
          if (document.querySelector('.sfzzm img')) {
            console.log('存在身份證正面')
            // 是否存在身份證反面
            if (document.querySelector('.sfzfm img')) {
              console.log('存在身份證反面')
              // 是否存在學歷證書
              if (document.querySelector('.xlzs img')) {
                console.log('存在學歷證書')
                if (this.ydxy) {
                  this.tijiaoIsShow = false
                }
              } else {
                Toast('請上傳學歷證書')
                this.tijiaoIsShow = true
              }
            } else {
              Toast('請上傳身份證反面') 
            }
          } else {
            Toast('請上傳身份證正面')
          }
        } else if (this.dbr == '擔保人不是本人') {
          if (this.checkUsername(this.dbrname)) {
            if (this.checkIdCard(this.dbridCard)) {
              if (this.checkTel(this.dbrzyzh)) {
                if (document.querySelector('.sfzzm img')) {
                  console.log('存在身份證正面')
                  if (document.querySelector('.sfzfm img')) {
                    console.log('存在身份證反面')
                    if (document.querySelector('.xlzs img')) {
                      console.log('存在學歷證書')
                      this.tijiaoIsShow = false
                    } else {
                      Toast('請上傳學歷證書')
                    }
                  } else {
                    Toast('請上傳身份證反面')
                  }
                } else {
                  Toast('請上傳身份證正面')
                }
              } else {
                Toast('請輸入擔保人展業證號')
              }
            } else {
              Toast('請輸入擔保人身份證號')
            }
          } else {
            Toast('請輸入擔保人姓名')
          }
        } else {
          Toast('請選擇擔保人是否為本人')
        }
      } else {
        Toast('請輸入正確的電話號碼')
      }
    } else {
      Toast('請輸入正確的身份證號')
    }
  } else {
    Toast('請輸入正確的姓名')
  }
}
View Code

單個if語句優化

優化前

if (flag) {
 this.handleFn()
}

優化后

flag && this.handleFn()
// handleFn是普通函數

 

另外如果遇到有很多的if語句,但是執行的功能函數卻是一致的情況,我們可以用”邏輯與“或者”邏輯或“來把他們合並成一個表達式。如果我們這些彼此獨立的條件判斷可以被視為同一次檢查的場景時,一次檢查的意圖明顯在可讀性上優於多次的條件檢查。我們來看一段代碼片段:

優化前

if (!(staffInfo.patientName && staffInfo.phone)) {
  // doSomething
}
...
if (!(staffInfo.phone && staffInfo.idCardNum)) {
  // doSomething
}

優化后

if(!(staffInfo.patientName && staffInfo.phone) || !(staffInfo.phone && staffInfo.idCardNum)){
  // doSomething
} 

if/else語句優化

if/else可以說在項目中遇到頻率是最高,通常可以這兩種策略優化

  • 排非策略
  • 三元運算符

排非策略

比如用戶登錄場景,如果用戶名和密碼輸入框為空,那么我們就提示用戶”用戶名和密碼不能為空”;如果有值,就執行登錄的操作。

優化前

  if (user && password) {
        // 邏輯處理
    } else {
        throw('用戶名和密碼不能為空!')
    }

優化后

if (!user || !password) return throw('用戶名和密碼不能為空!')
// 邏輯處理

表單提交時,需要提前排除那些提交不規范的內容,通常情況下,表單提交遇到不符合我們要求大於我們提交成功的情形,排非策略是個很不錯的選擇。

三元運算符

示例一

let allow = null
if(age >= 18){ 
   allow = '通過'; 
} else { 
   allow = '拒絕'; 
}

// 優化后
let allow = age >= 18 ? '通過' : '拒絕

 

示例二

if (flag) {
 success();
} else {
 fail();
}
  
//優化后
flag ? success() : fail();

三元運算符相比if/else來說,只需一行語句,代碼簡練精煉

單個if多條件優化

優化前

 

function test(type) {
  if (type === 'jpg' || type === 'png' || type === 'gif' || type === 'svg') {
    console.log("該文件為圖片");
  }
}

優化后

function test(type) {
    const imgArr = ['jpg', 'png', 'gif', 'svg']
    if (imgArr.includes(type)) {
        console.log("該文件為圖片")
    }
}

多個else if分支優化

多個else if通常是一個糟糕的選擇,它導致設計復雜,代碼可讀性差,並且可能導致重構困難。

if (this.type === 'A') {
  this.handleA();
} else if (this.type === 'B') {
  this.handleB();
} else if (this.type === 'C') {
  this.handleC();
} else if (this.type === 'D') {
  this.handleD();
} else {
  this.handleE();
}

 

我們經常遇到多個else if條件判斷代碼,隨着邏輯復雜性的增加,else if的代碼將變得越來越腫。

 

 

從上面的流程圖可以看出,不同條件分支的代碼具有很高的耦合度。先前的條件判斷將影響后續的代碼流,並且此類代碼在后續開發中難以維護。我們可以通過switchkey-valueMap來優化代碼。

switch

  switch(val){
    case 'A':
      handleA()
      break
    case 'B':
      handleB()
      break
    case 'C':
      handleC()
      break
    case 'D':
      handleD()
      break
  }

key-value

雖然switch語句在邏輯上確實比else if語句簡單,但是代碼本身也有點多。

其實我們對象枚舉,將條件與特定操作相關聯的鍵值

 

let enums = {
  'A': handleA,
  'B': handleB,
  'C': handleC,
  'D': handleD,
  'E': handleE
}
function action(val){
  let handleType = enums[val]
  handleType()
}

這種方式消除了所有條件語句,並使用鍵值對象存儲條件和操作之間的關系。當我們需要根據條件執行代碼時,我們不再需要使用else ifswitch語句來處理相應的動作,我們只需從中提取相應的函數handleType並執行它即可。

Map

實際上我們還可以通過Map來進一步的優化我們的代碼。

對比Object的話,Map具有許多優點

  • 對象的鍵只能是字符串或符號,而Map的鍵可以是任何類型的值。
  • 我們可以使用Map size屬性輕松獲取Map的鍵/值對的數量,而對象的鍵/值對的數量只能手動確定。
  • 具有極快的查找速度。

上面的例子可以優化如下:

let enums = new Map([
  ['A', handleA],
  ['B', handleB],
  ['C', handleC],
  ['D', handleD],
  ['E', handleE]
])

function action(val){
  let handleType = enums(val)
  handleType()
}

如果我們遇到多層復雜條件Map語句優勢就更明顯了!

if (mode == 'kline') {
    if (this.type === 'A') {
        this.handleA()
    } else if (this.type === 'B') {
        this.handleB()
    } else if (this.type === 'C') {
        this.handleC()
    } else if (this.type === 'D') {
        this.handleD()
    }
} else if ((mode = 'depth')) {
    if (this.type === 'A') {
        this.handleA()
    } else if (this.type === 'B') {
        this.handleB()
    } else if (this.type === 'C') {
        this.handleC()
    } else if (this.type === 'D') {
        this.handleD()
    }
}

對於上述如此復雜的場景,是否可以通過Map來進行優化?

其實我們只需要將不同的判斷語句連接成一個字符串,以便我們可以將條件和操作以鍵值格式關聯在一起。

 

let enums = new Map([
  ['kline_A', handleKlineA],
  ['kline_B', handleKlineB],
  ['kline_C', handleKlineC],
  ['kline_D', handleKlineD],
  ['kline_E', handleKlineE],
  ['depth_A', handleDepthA],
  ['depth_B', handleDepthB],
  ['depth_C', handleDepthC],
])

function action(mode, type){
  let key = `${mode}_${type}`
  let handleType = enums(key)
  handleType()
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM