参考文章JavaScript 复杂判断的更优雅写法
背景
我们编写js代码时经常遇到复杂逻辑判断的情况,通常大家可以用if/else或者switch来实现多个条件判断,但这样会有个问题,随着逻辑复杂度的增加,代码中的if/else/switch会变得越来越臃肿,越来越看不懂,那么如何更优雅的写判断逻辑,本文带你试一下。
案例
1. if /else if 与 switch
对于多个 if/else if 可以云 switch 替换
if(code === 1) {
//function 1
} else if(code === 2) {
//function 2
} else if(code === 3) {
//function 2
} else if(code === 4) {
// function 4
} else {
// function 5
}
替换为 switch
switch(code) {
case 1:
// function 1
break;
case 2:
case 3:
// function 2
break;
case 4:
// function 4
break;
default:
// function 5
break;
}
和 if/else if 相比, switch 相对清晰, 并且,当存在相同处理逻辑的时候,可以省略部分代码,如例子中的code =2 和 code=3。
2.Object 存储逻辑处理
当逻辑更复杂时,switch 显得较为臃肿,可以考虑采用Object 处理
const actions = {
'1': function() { /*function1*/ },
'2': function() { /*function2*/ },
'3': function() { /*function2*/ },
'4': function() { /*function4*/ },
'5': function() { /*function5*/ },
'default': function() { /*function default*/ }
}
function handleCode(code) {
function handle = actions[code] || action['defalut']
handle()
}
handleCode(code)
同案例1 相比,Object 存储逻辑代码更清晰,这种写法特别适合一元条件判断的情况。
3. Map 存储逻辑
Object 任存在一些问题,同ES6提供的Map 相比
- 对象自己的原型,所以一个对象总有一个"prototype"键。
- 对象的键只能是字符串或者Symbols,Map的键可以是任意值,包括对象
- 通过size属性很容易地得到一个Map的键值对个数,而对象的键值对个数只能手动确认。
可以看出,当判断调剂不是一元的时候,比如二元甚至更多的时候,Map相比Object 更适合
const actions = ()=>{
const functionA = ()=>{/*do this*/};
const functionB = ()=>{/*do this*/};
return new Map([
[{status:1,code:1}, functionA],
[{status:1,code:2}, functionA],
[{status:2,code:1}, functionA],
[{status:2,code:2}, functionA],
[{status:1,code:3}, functionA],
[{status:3,code:3}, functionB]
])
}
function handleEvent({status,code}){
let actionList = [ ... actions()].filter(([key,value])=>{
return key.status === status && key.code === code
})
actionList.forEach(([key,value])=>{
value.call(this)
})
}
handleEvent({status:3,code:3})
4.Map 存储逻辑升级
Map存储逻辑已经能满足日常需求了,但如果判断条件变得特别复杂,那你需要重复定义多条理逻辑,而往往这些逻辑里面很多都是相同的。
相比Object,Map的优势更加凸显,可以用正则类型作为key了,这样就有了无限可能。
const actions = ()=>{
const functionA = ()=>{/*do A*/};
const functionB = ()=>{/*do B*/};
const functionC = ()=>{/*do C*/};
const functionD = ()=>{/*do D*/}
return new Map([
[/^guest_[1-3]$/,functionA],
[/^guest_[4-6]$/,functionB],
[/^root_[7-9]$/,functionC],
[/^guest_.*$/,functionD]
])
}
function handleEvent({identity,code}){
let actionList = [ ... actions()].filter(([key,value])=>{
return key.test(`${identity}_$cdode}`)
})
actionList.forEach(([key,value])=>{
value.call(this)
})
}
handleEvent({identity:'guest',code:3})
借用原文的话,用数组循环的特性,符合正则条件的逻辑都会被执行,那就可以同时执行公共逻辑和单独逻辑,因为正则的存在,你可以打开想象力解锁更多的玩法
总结
各种种逻辑判断写法,包括:
- if/else
- switch
- 一元判断时:存到Object里
- 一元判断时:存到Map里
- 多元判断时:将condition存为Object存到Map里
- 多元判断时:将condition写作正则存到Map里
多元判断推荐使用Map,当处理逻辑相同的较多时,可以考虑使用正则结合Map。