前端中的if/else
在编写业务代码的时候,经常会出现条件判断,如果判断条件众多,就会出现if/else天梯,如果新的业务场景出现,就需要再添加一个if/else,这样的代码维护起来,简直是灾难。
if (status === 0) {
//do something
} else if (status === 1) {
//do something
} else if (status === 2) {
//do something
} else if (status === 3) {
// do something
}
如果新的业务场景出现,status === 4,那就需要再写一个if else,这样的代码可读性太差了。
简单if/else ----> 三元表达式
我们先从最简单的方式if/else进行改写
场景:
if (status === 0) {
action()
} else {
do();
}
像上面的状态判断,其实是没有必要的,那么如何进行判断的改写呢?
消除else
上面的else没有什么必要
if (status === 0) {
action();
return;
}
do();
使用三元表达式
status === 0 ? action() : do()
这样是不是更加简洁?毫无疑问
if/else 天梯转变为switch 天梯
经过了简单的if/else,那么我们来看一下,多重if/else如果进行改写?可以通过switch进行改良代码
switch (status) {
case 0:
// ...
case 1:
// ...
case 2:
// ...
default:
//...
}
但是这样无非只是将if else转变为了switch,提高了代码的可读性。当遇到新的场景的时候,还是需要到switch里面去修改对应的代码。
使用map,将代码配置化
定义一个map,里面存储对应的状态和对应状态的操作
const statusMap = new Map([
[0, doStatusZero],
[1, doStatusOne],
[2, doStatusThree]
]);
// 当遇到对应的状态的时候,只需要
statusMap.get(status)();
如果可以的化,可以将配置文件抽离,形成一个配置文件,如果有新的状态改变,只需要改变配置文件就ok了。
匹配对应的规则
使用map的好处,是代码可行性和整洁性提高了一个层次,但是只适用于一个单一的判断规则。如果具备多个判断的时候怎么办?假如一个判断是这样的,if(status === 0 && done === true && success == true), 那这样map简单配置的方式就不可以了,那既然简单不行,那就来电稍微复杂点的呗。
本质上if/else逻辑是一种状态匹配,转变为计算机的方式就是模式匹配,单一的模式不能满足需要,那就创建一个多元模式匹配。
场景:需要判断三种状态 status/done/success
多元状态匹配,需要进行两步操作
- 判断状态是否匹配
- 匹配完成要完成的动作
基于上面两种行为,我们将map抽象为下面的方式
const judgeMap = new Map([
[
(status, done, success) => status === 0 && done === 1 && success === 1,
() => {
// do something
}
],
[
(status, done, success) => status === 1 && done === 1 && success === 1,
() => {
// do something
}
]
]);
for (let [rule, action] of judgeMap) {
rule(status, done, success) && action()
}
总结
其实整个思想来源于表驱动法,使用表数据,存储对应的状态处理。其中表的概念,不局限于一个简单的map也可能是一个数组或者对象甚至是一个字符串,表的结构可以自己定义。
常见例子
如何优雅地输出今天星期几?
`今天星期${'日一二三四五六'.charAt((new Date()).getDay())}`
上面的例子可以看到表就是一个字符串
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。