論條件判斷的極致優化
北京的冬天還是來了,沒有一絲絲防備,滿腿的腿毛終究還是抵擋不住這沁人心脾的冷風,早上起來偷偷地把秋褲套上了。天氣雖冷,但我的心還是熱的,抽空整理了一下平時用到的優化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
模式匹配,想嚐鮮的兄弟自行檢視 => ofollow,noindex">傳送門
總結
ok,that's all.其實每一種都有自己的適合場景,用每一種都沒有任何問題,我常用的還是ifelse/switch。本文為便於快速理解,使用了比較簡單的demo,但是當情況比較複雜的時候,適當的使用一些技巧或者設計模式,一定程度上可以讓程式碼更清爽一些,更具拓展性。全憑個人習慣,以同事接手你的專案不罵你為己任,everything is ok, belive you are best, you are my hero and i love you forever, mua~
