相信在作业务开发的时候你们总会由于疯狂的需求变动或者时间的紧迫性不得已写下许多垃圾代码,而后给本身留下个TODO:下次优化(实际上事后就忘了)
(说的就是我没错了!)。git
而后等到某一天这些代码出了问题以后,你来回看这段代码,oh~~~,那可能会让你怀疑人生,因此今天就让咱们来聊聊在业务开发里常常会使用到的if...else
如何优化吧。github
if (true) {
if (true) {
if (true) {
if (true) {
if (true) {
if (true) {
}
}
}
}
}
}
复制代码
凡事都不是一口能吃成胖子的,咱们先从最简单的优化方式提及:npm
switch...case
相比if...else
的多重嵌套,switch...case
的链式调用固然更加浅显易懂利于维护,当咱们的条件比较单一可是数量较大时咱们能够简单地直接使用switch...case
代替:bash
const a = 3;
//bad:
if (a === 1) {
consoel.log('a > 1');
}
if (a === 2) {
consoel.log('a > 2');
}
if (a === 3) {
consoel.log('a > 3');
}
if (a === 4) {
consoel.log('a > 4');
}
// good:
switch(a) {
case 1:
console.log('a = 1');
case 2:
console.log('a = 2');
case 3:
console.log('a = 3');
defaut:
console.log('blablabla');
}
复制代码
, 可是这样写仍是让咱们以为有些太多了,毕竟多写了那么多的case
(滑稽),因而爱折腾的朋友就须要多动动脑子了。函数
object
相信你们都很了解,在js的对象里是使用的key-value
形式存储数据的,而想咱们上面的判断条件只有一个参数,只须要判断参数是否等于定值便可,那咱们是否是能够在这上面作点文章呢?好比使用key
代替判断条件,使用value
代替知足条件时的判断式:优化
const judegeMap = {
1: () => { console.log('a = 1') },
2: () => { console.log('a = 2') },
3: () => { console.log('a = 3') },
4: () => { console.log('a = 4') }
}
judgeMap[a]();
复制代码
看,这样是否是就好多啦~,可是仔细想一想,这样就够了吗?在业务开发中,if
的值永远不可能单单只是一个定值,判断式也千奇百怪,因此让咱们继续ui
咳咳,彷佛说了一个不得了的名词。咱们在这里就不聊这个名词的概念问题了,为何说起这位,只是由于咱们接下来要聊的东西彷佛挺像这么一回事。spa
首先看看咱们的if...else
,仔细想一想,它像不像是一颗树呢:由一个一个顶层的判断和其下其下包含的多个子级的判断组成:code
if (a > b) {
if (a > 10) {
if (a < 22) {
...
}
...
}
if (b > 12) {
...
}
...
}
复制代码
由以上例子能够看出咱们的决策树
由顶层的判断:a>b
和子集的判断a > 10, a < 22, b > 12
组合而成。整个树的执行,又只须要从其中逐层向下摘取出知足断定条件的部分。而后依次执行便可。由此咱们能够作出以下优化:对象
function aIsBiggerThanb() {
...doSomething
}
function aIsBiggerThan10() {
...doSomething
}
function aIsSmallerThan22() {
...doSomething
}
function bIsBiggerThan12() {
...doSomething
}
const judgeArray = [
{
condition: a > b,
callback: aIsBiggerThanb
},
{
condition: a > b && a > 10,
callback: aIsBiggerThan10
},
{
condition: a > b && a > 10 && a < 22,
callback: aIsSmallerThan22
},
{
condition: a > b && b > 12,
callback: bIsBiggerThan12
}
];
const callbackArray = judgeArray.reduce((eventArray, item) => {
item.condition && eventArray.push(item.callback)
return eventArray;
}, [])
for (let id in callbackArray) {7lki9
callbackArray[id]();
}
复制代码
这样作能够大大增长你的代码的可读性和可维护性,可是随之会增长更多的代码编写量,因此在这种状况下,我造了一个简单的轮子解决这种问题,让咱们再也不须要本身手动的编写决策树和正确决策的摘取过程,只须要关注业务的逻辑便可~
你能够经过yarn
或者npm
安装choicejs
$ npm install choicejs
$ yarn add choicejs
复制代码
const choicejs = require('choicejs').Choice;
import { Choice } from 'choicejs'
复制代码
add(description: string, condition: boolean, callback: any, extend?: string)
该方法是用来增长你的选择的,有四个参数,description
表明你对当前选择的描述,该项千万不要重复,不然后面增长的选择会覆盖以前的,第二个选项就是判断条件,第三个代指知足判断条件时的回调方法,最后一个参数为可选参数,代指继承于某项描述,就比如嵌套的if...else
嵌套于某个条件同样。
一个栗子:
const judgeTree = new Choice();
const logAisBiggerThan1() {
console.log('a > 1')
};
const logAisSmallerThan9() {
console.log('a < 9');
}
const a = 3;
judgeTree
.add('biggerThan1', a > 1, logAisBiggerThan1)
.add('smallerThan9', a < 9, logAisSmallerThan9, 'biggerThan1')
复制代码
use()
简单暴力的方法,add
用来定义,而use
就是用来执行。若是没有use
,那么定义好的决策树就像是一个定义好的函数,没有()
它就毫无卵用~
栗子:
judgeTree.use();
// 注意,judgeTree 是支持链式调用的,因此放心大胆地将 use() 接在 add() 以后使用吧~
复制代码
destroy()
简单的销毁方法,使用完以后能够选择清空当前实例中的全部信息,一般做为最后一步使用,在此就不举例啦~
具体使用例子,能够参照我在Runkit
上的示例代码: Runkit示例
虽然借着文章厚颜无耻的推荐了一下本身的轮子,可是但愿各位看官仍是能从个人一些粗浅看法中学到一些东西,若是喜欢个人文章,麻烦请点个赞哦~
(固然,点个star我也是很开心的哈哈哈~)