JavaScript 优雅的条件判断...别说我没告诉你

86 阅读3分钟

在搬砖的日常中,会遇到很多条件判断如果只用 if else | swith case ,当条件过多时,代码就很臃肿

例如下面这串代码~

/**
     * 按钮点击事件
     * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 5 系统取消
     */
const onButtonClick = (status)=>{
      if(status == 1){
        sendLog('processing')
        jumpTo('IndexPage')
      }elseif(status == 2){
        sendLog('fail')
        jumpTo('FailPage')
      }elseif(status == 3){
        sendLog('fail')
        jumpTo('FailPage')
      }elseif(status == 4){
        sendLog('success')
        jumpTo('SuccessPage')
      }elseif(status == 5){
        sendLog('cancel')
        jumpTo('CancelPage')
      }else {
        sendLog('other')
        jumpTo('Index')
      }
    }
 
const onButtonClick = (status)=>{
      switch (status){
        case1:
          sendLog('processing')
          jumpTo('IndexPage')
          break
        case2:
        case3:
          sendLog('fail')
          jumpTo('FailPage')
          break
        case4:
          sendLog('success')
          jumpTo('SuccessPage')
          break
        case5:
          sendLog('cancel')
          jumpTo('CancelPage')
          break
        default:
          sendLog('other')
          jumpTo('Index')
          break
      }
    }

优化之 对象形式(策略模式)

const actions = {
      '1': ['processing','IndexPage'],
      '2': ['fail','FailPage'],
      '3': ['fail','FailPage'],
      '4': ['success','SuccessPage'],
      '5': ['cancel','CancelPage'],
      'default': ['other','Index'],
    }
 
    /**
     * 按钮点击事件
     * @param {number} status 活动状态:1开团进行中 2开团失败 3 商品售罄 4 开团成功
     */const onButtonClick = (status)=>{
      let action = actions[status] || actions['default'],
          logName = action[0],
          pageName = action[1]
          sendLog(logName)    
          jumpTo(pageName)
    }

优化之 Map对象

const actions = newMap([
      [1, ['processing','IndexPage']],
      [2, ['fail','FailPage']],
      [3, ['fail','FailPage']],
      [4, ['success','SuccessPage']],
      [5, ['cancel','CancelPage']],
      ['default', ['other','Index']]
    ])
    /**
     * 按钮点击事件
     * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 商品售罄 4 开团成功 
     */const onButtonClick = (status)=>{
      let action = actions.get(status) || actions.get('default')
      sendLog(action[0])
      jumpTo(action[1])
    }

对象形式和Map对象区别在于:普通对象形式的key值只能是字符串或者Symbol,但是Map的值可以是任意值,甚至是正则表达式

多元条件判断:

/**
 * 按钮点击事件
 * @param {number} status 活动状态:1开团进行中 2开团失败 3 开团成功 4 商品售罄 5 有库存未开团
 * @param {string} identity 身份标识:guest客态 master主态
 */
const onButtonClick = (status,identity)=>{
  if(identity == 'guest'){
    if(status == 1){
      //do sth
    }else if(status == 2){
      //do sth
    }else if(status == 3){
      //do sth
    }else if(status == 4){
      //do sth
    }else if(status == 5){
      //do sth
    }else {
      //do sth
    }
  }else if(identity == 'master') {
    if(status == 1){
      //do sth
    }else if(status == 2){
      //do sth
    }else if(status == 3){
      //do sth
    }else if(status == 4){
      //do sth
    }else if(status == 5){
      //do sth
    }else {
      //do sth
    }
  }
}

优化多元判断条件

核心是将两个条件拼接成字符串,然后将该字符串用作为key值

方案一:

const actions = new Map([
  ['guest_1', ()=>{/*do sth*/}],
  ['guest_2', ()=>{/*do sth*/}],
  ['guest_3', ()=>{/*do sth*/}],
  ['guest_4', ()=>{/*do sth*/}],
  ['guest_5', ()=>{/*do sth*/}],
  ['master_1', ()=>{/*do sth*/}],
  ['master_2', ()=>{/*do sth*/}],
  ['master_3', ()=>{/*do sth*/}],
  ['master_4', ()=>{/*do sth*/}],
  ['master_5', ()=>{/*do sth*/}],
  ['default', ()=>{/*do sth*/}],
])
 
/**
 * 按钮点击事件
 * @param {string} identity 身份标识:guest客态 master主态
 * @param {number} status 活动状态:1 开团进行中 2 开团失败 3 开团成功 4 商品售罄 
 */
const onButtonClick = (identity,status)=>{
  let action = actions.get(`${identity}_${status}`) || actions.get('default')
  action.call(this)
}

方案二:

/*
* 和map对象同理
*/
 
const actions = {
  'guest_1':()=>{/*do sth*/},
  'guest_2':()=>{/*do sth*/},
  //....
}
 
const onButtonClick = (identity,status)=>{
  let action = actions[`${identity}_${status}`] || actions['default']
  action.call(this)
}

升级版本

const actions = ()=>{
  const functionA = ()=>{/*do sth*/}
  const functionB = ()=>{/*do sth*/}
  return new Map([
    [{identity:'guest',status:1},functionA],
    [{identity:'guest',status:2},functionA],
    [{identity:'guest',status:3},functionA],
    [{identity:'guest',status:4},functionA],
    [{identity:'guest',status:5},functionB],
    //...
  ])
}
 
const onButtonClick = (identity,status)=>{
  let action = [...actions()].filter(([key,value])=>(key.identity == identity && key.status == status))
  action.forEach(([key,value])=>value.call(this))
}

异于常人的方式!!!

这里将正则表达式作为了key值

const actions = ()=>{
  const functionA = ()=>{/*do sth*/}
  const functionB = ()=>{/*do sth*/}
  const functionC = ()=>{/*send log*/}
  return new Map([
    [/^guest_[1-4]$/,functionA],
    [/^guest_5$/,functionB],
    [/^guest_.*$/,functionC],
    //...
  ])
}
 
const onButtonClick = (identity,status)=>{
  let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
  action.forEach(([key,value])=>value.call(this))
}