背景
北京的冬天還是來了,沒有一絲絲防備,滿腿的腿毛終究還是抵擋不住這沁人心脾的冷風,早上起來偷偷地把秋褲套上了。天氣雖冷,但我的心還是熱的,抽空整理了一下平時用到的優化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~