浅谈优化if...else

为什么要优化if..else

相信在作业务开发的时候你们总会由于疯狂的需求变动或者时间的紧迫性不得已写下许多垃圾代码,而后给本身留下个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]();
}
复制代码

这样作能够大大增长你的代码的可读性和可维护性,可是随之会增长更多的代码编写量,因此在这种状况下,我造了一个简单的轮子解决这种问题,让咱们再也不须要本身手动的编写决策树和正确决策的摘取过程,只须要关注业务的逻辑便可~

choicejs

install

你能够经过yarn或者npm安装choicejs

$ npm install choicejs
$ yarn add choicejs
复制代码

require or import

const choicejs = require('choicejs').Choice;

import { Choice } from 'choicejs'
复制代码

usage

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我也是很开心的哈哈哈~)

choicejs源码

相关文章
相关标签/搜索