简单的逻辑判断常用的优化方法

||

var a = 1;
if(a){
    a = 1;
}else{
    a = 0;
};
//可写成
a = a || 0;

三元表达式

var a = 1;
var b = 2;
var c = 3;
var d = 4;
if(a == b){
    a = c;
}else{
    a = d;
}
//可写成
a = (a == b) ? c : d;

提前返回

复杂的逻辑判断常用的优化方法

日常开发经常会遇到复杂的条件判断, 一般做法就是用if/else, 如何使用更优雅的方式来实现呢?

if(status === 1) {
    sendLog('processing')
    jumpTo('IndexPage')
  } else if(status === 2) {
    sendLog('fail')
    jumpTo('FailPage')
  } else if(status === 3) {
    sendLog('fail')
    jumpTo('FailPage')
  } else {
    sendLog('other')
    jumpTo('Index')
  }

switch

switch (status) {
    case 1:
      sendLog('processing')
      jumpTo('IndexPage')
      break
    case 2:
    case 3:
      sendLog('fail')
      jumpTo('FailPage')
      break
    default:
      sendLog('other')
      jumpTo('Index')
  }

对象映射

const actions = {
  '1': ['processing', 'IndexPage'],
  '2': ['fail', 'FailPage'],
  '3': ['fail', 'FailPage'],
  'default': ['other', 'Index']
}
const clickHandler = (status) => {
  let action = actions[status] || actions['default'], 
    LogName = action[0],
    pageName = action[1]
  sendLog(LogName)
  jumpTo(pageName)
}

map

const actions = new Map([
  ['1', ['processing', 'IndexPage']],
  ['2', ['fail', 'FailPage']],
  ['3', ['fail', 'FailPage']],
  ['default', ['other', 'Index']]
])

const clickHandler = (status) => {
  let action = actions.get(status) || actions.get('default')
  sendLog(action[0])
  jumpTo(action[1])
}

新需求

原先只是判断status的状态, 若现在还需同时判断用户:

if(identity == 'guest') {
    if(status === 1) {
      // to do something
    } else if (status === 2) {
      // to do something
    } else if (status === 3) {
      // to do something
    } else {
      // to do something
    }
  } else if(identity == 'master') {
    if(status === 1) {
      // to do something
    } else if (status === 2) {
      // to do something
    } else {
      // to do something
    }
  }
}

map

const actions = {new Map([
  ['guest_1', () => {/* to do something */}],
  ['guest_2', () => {/* to do something */}],
  ['guest_3', () => {/* to do something */}],
  ['master_1', () => {/* to do something */}],
  ['master_2', () => {/* to do something */}],
  ['master_3', () => {/* to do something */}],
  ['default', () => {/* to do something */}],
])}

上述代码的逻辑是:

  • 把两个条件拼接成字符串
  • 以拼接的条件字符串作为key, 以处理函数作为值的Map对象进行查找并执行

当然, 也可以用Object对象来实现

const actions = {
  'guest_1': () => {/* to do something */},
  'guest_2': () => {/* to do something */},
  'guest_3': () => {/* to do something */},
  'master_1': () => {/* to do something */},
  'master_2': () => {/* to do something */},
  'master_3': () => {/* to do something */},
  'default': () => {/* to do something */}
}

map(以ObjectKey

const actions = new Map([
  [{identity: 'guest', status: 1}, () => {/* to do something */}],
  [{identity: 'guest', status: 2}, () => {/* to do something */}]
  [{identity: 'guest', status: 3}, () => {/* to do something */}]
])

const clickHandler = (identity, status) {
  let action = [...actions].filter((key, value) => {key.identity === identity && key.status === status})
  action.forEach(([key, value]) => {value.call(this)})
}

新需求

假如在guest情况下, status 1~4 的处理逻辑是一样的:

const actions = 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 clickHandler = (identity, status) {
  let action = [...actions].filter((key, value) => {key.identity === identity && key.status === status})
  action.forEach(([key, value]) => {value.call(this)})
}

这样写, 基本也满足需求了, 但重复的写4次functionA, 但如果identity的状态有3种,status的状态有30种呢?
如果是此种情况, 也可以考虑用正则表达式, 如:

const actions = new Map([
  [/^guest_[1-4]$/, functionA],
  [/^guest_5$/, functionA],
])

const clickHandler = (identity, status) {
  let action = [...actions].filter((key, value) => {key.test(`${identity}_${status}`)})
  action.forEach(([key, value]) => {value.call(this)})
}

假如需求变成, 凡是guest的情况, 都要发送一个日志埋码, 不同的status的情况, 也要单独做处理. 那么我们可以考虑这样写:

const actions = new Map([
  [/^guest_[1-4]$/, functionA],
  [/^guest_5$/, functionA],
  [/^guest_.$/, functionC],
])

const clickHandler = (identity, status) {
  let action = [...actions].filter((key, value) => {key.test(`${identity}_${status}`)})
  action.forEach(([key, value]) => {value.call(this)})
}

zhouzhou
1.5k 声望76 粉丝

web前端