优化实战 第 29 期 - 代码中大量 if/else 的优化策略

3,836 阅读2分钟

在产品的快速迭代中,往往追求的是开发速度,甚至是忽略了代码的可读性与扩展性,不合理的大量使用条件判断语句,使我们的程序复杂度大大提升。后续代码的扩展和维护就会变得非常困难且容易出错

单个 if 语句单条件优化

  • 优化前

    if (flag) {
      this.handleFunc()
    }
    
  • 优化后

    flag && this.handleFunc()
    

    如果有很多的 if 语句,但执行的功能函数是同一个的情况下,可以使用 &|| 逻辑运算符合成一个表达式,增强其 可读性

单个 if 语句多条件优化

  • 优化前

    if (filetype === 'image/png' || filetype === 'image/jpeg' || filetype === 'image/gif') {
      console.log('文件类型为图片')
    }
    
  • 优化后

    const mimetypes = ['image/png', 'image/jpeg', 'image/gif']
    if (mimetypes.includes(filetype)) {
      console.log('文件类型为图片')
    }
    

单个 if/else 语句优化

  • 优化前

    let accountStatus = ''
    if (enabled) {
      accountStatus = '正常'
    } else {
      accountStatus = '禁用'
    }
    
  • 优化后

    const accountStatus = enabled ? '正常' : '禁用'
    

    只需要一行语句,代码既简练又易读

多个 else if 分支优化

  • 优化前

    if (operation === 'open') {
      this.handleOpen()
    } else if (operation === 'pause') {
      this.handlePause()
    } else if (operation === 'edit') {
      this.handleEdit()
    } else {
      this.handleDelete()
    }
    

    设计复杂,代码可读性差,随着逻辑复杂性的增加,代码会变得越来越臃肿

    condition.png

    不同条件分支的代码具有很高的耦合度。前边的条件判断影响后续的代码流,这样的代码对于后期的维护非常的不友好

  • 优化后

    switch(operation) {
      case 'open': 
        this.handleOpen()
        break
      case 'pause':
        this.handlePause()
        break
      case 'edit':
        this.handleEdit()
        break
      default:
        this.handleDelete()
    }
    

多个 if 语句多层复杂条件优化

  • 优化前

    if (mode === 'kwai') {
      if (operation === 'open') {
        this.handleKwaiOpen()
      } else if (operation === 'pause') {
        this.handleKwaiPause()
      } else if (operation === 'edit') {
        this.handleKwaiEdit()
      } else {
        this.handleKwaiDelete()
      }
    } else if (mode === 'tencent') {
      if (operation === 'open') {
        this.handleTencentOpen()
      } else if (operation === 'pause') {
        this.handleTencentPause()
      } else if (operation === 'edit') {
        this.handleTencentEdit()
      } else {
        this.handleTencentDelete()
      }
    }
    
  • 优化后

    const operations = Object.assign(Object.create(null), {
      'kwai': new Map([
        ['open', handleKwaiOpen],
        ['pause', handleKwaiPause],
        ['edit', handleKwaiEdit],
        ['delete', handleKwaiDelete],
      ]),
      'tencent': new Map([
        ['open', handleTencentOpen],
        ['pause', handleTencentPause],
        ['edit', handleTencentEdit],
        ['delete', handleTencentDelete],
      ])
    })
    
    function(mode, type) {
      console.log('handleType', operations[mode].get(type))
    }
    

可选链运算符

  • 优化前

    if (res && res.userInfo && res.userInfo.roles) {
      const roles = res.userInfo.roles
    }
    

    对象属性层层判断是否存在不仅麻烦还会产生冗余的代码

  • 优化后

    const roles = res?.userInfo?.roles
    

优化总结

if-else 不超过 2 层,块中代码 1~5 行,直接写到块中,否则封装为方法

if-else 超过 2 层,但块中的代码不超过 3 行,尽量使用 Switch 语句

if-else 超过 2 层,且块中代码超过 3 行,尽量使用 策略模式

一起学习,加群交流看 沸点