淺談優化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源碼

相關文章
相關標籤/搜索