代碼簡潔之道(判斷篇)


第一個例子

if (state === 1) {
    return true
} else if (state === 2) {
    return true
} else if (state === 3) {
    return true
} else if (state === 4){
    return true
} else {
    return false
}

你首先想到的可能是 使用 switch case, 我們使用 switch case 來改寫它:

switch (state) {
    case 1: return true
        break;
    case 2: return true
        break;
    case 3: return true
        break
    case 4: return true
        break
    default: return false
        break
}

看起來有些條理了, 但我們應對這類情況,可以將他進一步優化,觀察發現:

  • 都是判斷 state
  • 判斷后都做了相同的事情 (return true)

我們用 Array.includes 來優化它:

includes() 方法用來判斷一個數組是否包含一個指定的值,如果是返回 true,否則false。

  • 參數一:必須。需要查找的元素值。
  • 參數二:可選。從該索引處開始查找 searchElement。如果為負值,則按升序從 array.length + fromIndex 的索引開始搜索。默認為 0。
const states = [1, 2, 3, 4]
if (states.includes(state) {
    return true
}

這樣是不是更簡單,代碼量也更少了,同時也方便管理 states, 因為現在所有 state 都被加到 一個數組 (states) 了。

如果不是做相同的事情呢(即每一種狀態下我們需要做不同的事情)?例如下面這種情況:

if (state === 1) {
    // do something
} else if (state === 2) {
    // do something
} else if (state === 3) {
    // do something
} else if (state === 4){
    // do something
} else {
    // do something
}

我們可以使用對象來優化它:

const actions = {
    1: () => { /*do something*/ },
    2: () => { /*do something*/ },
    3: () => { /*do something*/ },
    4: () => { /*do something*/ },
    'default': () => { /*do something*/ }
}

actions[state]() || actions['default']();
  • 可讀性更高
  • 更易於維護

原理很簡單,只需要通過對象的 key 找到對象的值, 而對應的值又是一個 func, 同時來執行它就可以了。

第二個例子

if (type === 'firstType') {
    if (state === 1) {/*do something*/
        // do something
    } else if (state === 2) {
        // do something
    } else if (state === 3) {
        // do something
    } else if (state === 4){
        // do something
    } else {
        // do something
    }
} else if (type === 'secondType') {
    if (state === 1) {
        // do something
    } else if (state === 2) {
        // do something
    } else if (state === 3) {
        // do something
    } else if (state === 4){
        // do something
    } else {
        // do something
    }
}

觀察上面的代碼,發現外層又套了一層判斷,這在日常業務中也是十分常見的,例如一個 APP 需要區分不同身份,或者多端應用中。。。

仿照上面的例子稍加變動我們就能將它優化:

const actions = {
  'firstType_1': ()=>{ /*do something*/ }],
  'firstType_2': ()=>{ /*do something*/ }],
  'firstType_3': ()=>{ /*do something*/ }],
  'firstType_4': ()=>{ /*do something*/ }],
  'secondType_1': ()=>{ /*do something*/ }],
  'secondType_2': ()=>{ /*do something*/ }],
  'secondType_3': ()=>{ /*do something*/ }],
  'secondType_4': ()=>{ /*do something*/ }],
  'default': ()=>{ /*do something*/ }]
}

const action = actions[`${type}_${state}`] || actions['default']

我們給對象的 key 設置為一個字符串,字符串由兩個條件通過 _ (當然你可以隨意) 鏈接在一起,它所對應的值依然是一個 func 。
同時用兩個變量通過模板字符串的形式鏈接在一起,實現與上個例子相同的效果。

我們還可以使用 Map 來優化它:

const actions = new Map([
  ['firstType_1', ()=>{ /*do something*/ }],
  ['firstType_2', ()=>{ /*do something*/ }],
  ['firstType_3', ()=>{ /*do something*/ }],
  ['firstType_4', ()=>{ /*do something*/ }],
  ['secondType_1', ()=>{ /*do something*/ }],
  ['secondType_2', ()=>{ /*do something*/ }],
  ['secondType_3', ()=>{ /*do something*/ }],
  ['secondType_4', ()=>{ /*do something*/ }],
  ['default', ()=>{ /*do something*/ }]
])

const action = actions.get(`${type}_${state}`) || actions.get('default')

Map 類似於對象,也是鍵值對的集合,但是“鍵”的范圍不限於字符串,各種類型的值(包括對象)都可以當作鍵。

原理與上個是一樣的,不過是將對象的形式改為了 Map 的形式,發現這樣稍微復雜了一些,但是我們可以用它來處理更復雜的情況。

我們假設 firstType 中 state 為 1-3 都做相同的事,那么可以這樣寫:

const actions = new Map([
  ['/^firstType_[1-3]$/', ()=>{ /*do something*/ }],
  ['firstType_4', ()=>{ /*do  something*/ }],
  // ...
  ['default', ()=>{ /*do something*/ }]
])

很顯然使用正則表達式能夠減少重復的代碼, 也能帶來更多可能性,處理更復雜的情況。

如果對應的方法中出現大量邏輯代碼,那么我們可以將 actions 封裝為一個函數。進一步來優化它,:

const actions = () => {
    const fn1 = () => {}
    const fn2 = () => {}
    return new Map([
                    ['/^firstType_[1-3]$/', fn1],
                    ['firstType_4', fn2],
                    // ...
                 ])
}

這樣做的好處是把對應的邏輯抽離出來,更加方便日后維護,條理更加清晰。

參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM