蝦扯蛋之條件判斷的極致優化

逍遙自在0121發表於2018-12-07

背景

北京的冬天還是來了,沒有一絲絲防備,滿腿的腿毛終究還是抵擋不住這沁人心脾的冷風,早上起來偷偷地把秋褲套上了。天氣雖冷,但我的心還是熱的,抽空整理了一下平時用到的優化ifelse的方法,與君分享,歡迎指正。

邏輯運算

if (jinChengWu) {
    boyFriend = jinChengWu;
} else {
    boyFriend = 'you';
}
//改寫為↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//邏輯或
boyFriend = jinChengWu || 'you';


if (high) {
    if (haveMoney) {
        if (handsome) {
            boyFriend = 'you';
        }
    }
}
//改寫為↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//邏輯與
boyFriend = high && haveMoney && handsome && 'you';

複製程式碼

三目運算

//三目運算
if (age < 50) {
    people = 'boy';
} else {
    people = 'man';
}

//改寫為↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

people = (age < 50) ? 'boy' : 'man';
複製程式碼

switch

多個ifelse,換成switch可以得到更快的程式碼,case概率最大的放前面,概率最小的放後面,進一步優化switch

if (star === 10) {
    console.log('青銅');
} else if (star === 20) {
    console.log('白銀');
} else if (star === 30) {
    console.log('黃金');
} else if (star === 40) {
    console.log('鉑金');
} else if (star === 50) {
    console.log('鑽石');
} else {
    console.log('星耀以上');
}

//改寫為↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

switch (star) {
    case 40:
        console.log('鉑金');
        break;
    case 30:
        console.log('黃金');
        break;
    case 50:
        console.log('鑽石');
        break;
    case 20:
        console.log('白銀');
        break;
    case 10:
        console.log('青銅');
        break;
    default:
        console.log('星耀以上');
        break;
}
複製程式碼

策略模式

根據ifelse封裝策略類,每次去取策略。策略可以是object鍵值對,Map鍵值對,value可以是字串,函式等等任何處理程式,可根據自身喜好結合實際需求進行配置。

//策略
const levelStrategy = new Map([
    [10, '青銅'],
    [20, '白銀'],
    [30, '黃金'],
    [40, '鉑金'],
    [50, '鑽石'],
    ['other', '星耀以上']
]);

//環境
const getMyLevel = starNum => levelStrategy.get(starNum);
//使用
const myLevel = getMyLevel(50); // '鑽石'
複製程式碼

職責鏈模式

連線成一條鏈,沿著鏈路走,誰能解決我的問題就停下來找誰解決,解決不了就交與下一個人。

//職責鏈模式 
const judgeQt = starNum => {
    if (starNum === 10) {
        console.log('青銅');
    } else {
        return 'nextSuccess'
    }
}
const judgeBy = starNum => {
    if (starNum === 20) {
        console.log('白銀');
    } else {
        return 'nextSuccess'
    }
}
const judgeOtherLevel = starNum => {
    if (starNum >= 30) {
        console.log('黃金以上');
    } else {
        return 'nextSuccess'
    }
}
// 鏈路程式碼
Function.prototype.after = function (fn) {
    const self = this
    return function () {
        const result = self.apply(self, arguments)
        if (result === 'nextSuccess') {
            return fn.apply(self, arguments)
        }
    }
}
//用法
const getLevel = judgeQt.after(judgeBy).after(judgeOtherLevel);
getLevel(20);// '白銀'
複製程式碼

惰性載入函式

有些方法中的ifelse,其實只需要判斷一次,就不需要再判斷了,無論之後什麼時候再呼叫這個方法,和第一次呼叫這個方法的執行結果是一樣的,此時我們就沒必要再去進行條件判斷,就可以使用惰性載入函式。

一個合適的場景就是瀏覽器的能力檢測,以事件繫結為例,整個程式中,我們會呼叫很多次addEvent進行事件繫結,但是,其實我們不必每次都走一次ifelse進行能力判斷,chrome中,必然是支援addEventListener,無論什麼時候呼叫,都會進入第一個判斷,少走一次判斷,都會加快一些執行速度。

const oA = document.getElementById('a'),
    oB = document.getElementById('b');
//事件繫結
function addEvent(type, el, fn) {
    if (window.addEventListener) {
        console.log('IF執行了');
        el.addEventListener(type, fn, false);
    }
    else if (window.attachEvent) {
        el.attachEvent('on' + type, fn);
    }
}

addEvent('click', oA, () => { alert('哈哈') });
addEvent('click', oB, () => { alert('嘻嘻') });
//事件繫結成功 列印 2 次 'IF執行了' if條件執行2次

//改寫為↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

//惰性載入升級
function addEvent(type, el, fn) {
    if (window.addEventListener) {
        console.log('IF執行了');
        addEvent = function (type, el, fn) {
            el.addEventListener(type, fn, false);
        }
    }
    else if (window.attachEvent) {
        addEvent = function (type, el, fn) {
            el.attachEvent('on' + type, fn);
        }
    }
    addEvent(type, el, fn);
}

addEvent('click', oA, () => { alert('哈哈') });
addEvent('click', oB, () => { alert('嘻嘻') });
//事件繫結成功 列印 1 次 'IF執行了' if條件只執行1次
複製程式碼

Pattern matching

模式匹配,想嚐鮮的兄弟自行檢視 => 傳送門

總結

ok,that's all.其實每一種都有自己的適合場景,用每一種都沒有任何問題,我常用的還是ifelse/switch。本文為便於快速理解,使用了比較簡單的demo,但是當情況比較複雜的時候,適當的使用一些技巧或者設計模式,一定程度上可以讓程式碼更清爽一些,更具擴充性。全憑個人習慣,以同事接手你的專案不罵你為己任,everything is ok, belive you are best, you are my hero and i love you forever, mua~

image

相關文章