日常开发中,复杂的逻辑判断不说经常遇到,但肯定是会遇到的。通常我们会用 if else 或者 switch 来实现这些逻辑的判断,但随着逻辑复杂度的增高,if else 和 switch 会变得异常复杂,难于阅读与维护,今天我们就讨论一下如何优雅的解决这个问题。
示例代码:
let toView = (flag = 1) => {
if (flag === 1) {
view('页面一')
} else if (flag === 2) {
view('页面二')
} else if (flag === 3) {
view('页面二')
} else if (flag === 4) {
view('页面四')
}
}
上面的 toView 方法,根据 flag 值的不同,进入不同的页面。大家一看,这还不简单,用 switch 改写一下不就好了。
let toView = (flag = 1) => {
switch (flag) {
case 1:
view('页面一')
break
case 2:
case 3:
view('页面二')
break
case 4:
view('页面四')
break
}
}
细心的同学还会发现,2 和 3的逻辑是一样的,还可以省去一段前面的逻辑处理,哎呀真不错,哈哈。以上都是常规操作,下面开始进入正题了。
一个更简单方案,直接上代码:
const flagMirror = {
'1': '页面一',
'2': '页面二',
'3': '页面二',
'4': '页面四'
}
let toView = (flag = 1) => {
view(flagMirror[flag + ''])
}
看到这里,是不是觉得这个方案挺巧妙的呢,它把判断条件作为对象的key,实际处理逻辑当作 value,然后通过属性访问,完美解决了臃肿的 if else 书写。既然说到键值对,那么就不由得联想到 ES6 的对象 Map,Map 对象的优势在于,它的 key 可以是任何类型,我们将上面的代码用Map对象改写如下:
const flagMirror = new Map([
[1, '页面一'],
[2, '页面二'],
[3, '页面二'],
[4, '页面四']
])
let toView = (flag = 1) => {
view(flagMirror.get(flag))
}
上面我们说的都是简单的条件判断,下面来看一个嵌套的 if 判断,示例代码如下:
let toView = (platform = '移动端', flag = 1) => {
if (platform === '移动端') {
if (flag === 1) {
view('移动页面一')
} else if (flag === 2) {
view('移动页面二')
} else if (flag === 3) {
view('移动页面二')
} else if (flag === 4) {
view('移动页面四')
}
} else if (platform === 'PC端') {
if (flag === 1) {
view('PC页面一')
} else if (flag === 2) {
view('PC页面二')
} else if (flag === 3) {
view('PC页面二')
} else if (flag === 4) {
view('PC页面四')
}
}
}
上面我们说了,Map对象的 key 可以是任何类型,那么我们可以这样改写上面的代码
const flagMirror = new Map([
[{ platform: '移动端', flag: 1 }, '移动页面一'],
[{ platform: '移动端', flag: 2 }, '移动页面二'],
[{ platform: '移动端', flag: 3 }, '移动页面二'],
[{ platform: '移动端', flag: 4 }, '移动页面四'],
[{ platform: 'PC端', flag: 1 }, 'PC页面一'],
[{ platform: 'PC端', flag: 2 }, 'PC页面二'],
[{ platform: 'PC端', flag: 3 }, 'PC页面二'],
[{ platform: 'PC端', flag: 4 }, 'PC页面四']
])
let toView = (platform = '移动端', flag = 1) => {
let result = Array.from(flagMirror)
.find(([key, value]) => key.platform === platform && key.flag === flag)
view(result[1])
}
个人觉得这种优化方式还是要根据实际情况进行取舍,毕竟代码重复率也挺高的,只是比 if else 的代码阅读性高那么一点点,看着更直观些。
那么我们再假设一种情况,就是 flag 值为 1 2 3 时,处理逻辑是一样的,比如都跳转到 【页面二】,那么我们上面的代码可以再次升级
const flagMirror = new Map([
[/^移动端[1-3]$/, '移动页面二'],
[/^移动端4$/, '移动页面四'],
[/^PC端[1-3]$/, 'PC页面二'],
[/^PC端4$/, 'PC页面四']
])
let toView = (platform = '移动端', flag = 1) => {
let result = Array.from(flagMirror)
.find(([key, value]) => key.test(`${platform}${flag}`))
view(result[1])
}
没想到吧,正则也可以用来当作 key,就是这么神奇。优化的大体思路就是这些了,希望以后写代码,除了 if else,大家还能灵活运用 Object 和 Map~