js中多條件對應相同返回值的優化寫法
阿新 • • 發佈:2022-04-21
需求描述
設計一種通用的、處理多條件具有相同行為的分支結構,示例場景:根據月份返回季節,1-3月返回春天,...
分析
- 方法1:if...else if...else 首先排除,可讀性和擴充套件性太差
- 方法2:switch 擴充套件性更好,但可讀性不是太好,且switch結構的終止語句可有可沒有的語法可能導致潛在的異常
- 方法3:物件屬性語法的可讀性和擴充套件性都比較好,但是需要重複書寫相同的行為
最終決定,基於方法3的物件語法做改進:
- 維護條件和行為使用物件陣列的形式:具體行為可以使用標誌符代替,方便後續直接根據標誌符呼叫相應的行為方法
{
行為識別符號1: [條件a1,條件a2, ... ],
行為識別符號2: [條件b1,條件b2, ... ],
}
- 定義一個通用的轉換方法,將1中的物件轉換成一對一對映結構的Object物件(或者對映等型別的物件)
- 基於2返回的Object物件(或其他型別的物件),使用三目運算子返回相應的行為識別符號或預設值
實現
以“月份——季節”舉例:
// 轉換方法 function transOptions(options) { let newOptions = {}; for (const action in options) { options[action].forEach(condition => (newOptions[condition] = action)); } return newOptions; } // 判斷方法 function getSeason(month) { const options = { spring: [1,2,3], summer: [4,5,6], autumn: [7,8,9], winter: [10,11,12], } let newOptions = transOptions(options); return newOptions[month] ? newOptions[month] : handleUnexpectedMonth(month); // 意外的月份值可以呼叫其他方法處理 }
改進
這裡的 options 可以使用 Map 型別,使得鍵的型別更加廣泛,如數字、物件等,對於非字串型別的條件和多元條件判定更為實用:
// 轉換方法 function transOptionsMap(options) { let newOptions = new Map(); for (const [action, conditions] of [...options.entries()]) { conditions.forEach(condition => newOptions.set(condition, action)); } return newOptions; } // 判斷方法 function getSeason(month) { const options = new Map([ // 1,2,3,4表示第N個季度 [1, [1,2,3]], [2, [4,5,6]], [3, [7,8,9]], [4, [10,11,12]], ]); let newOptions = transOptionsMap(options); return options.get(month) ? options.get(month) : handleUnexpectedMonth(month); // 意外的月份值可以呼叫其他方法處理 }