不管是平時在學習js中還是在項目書中寫js代碼,都避免不了一個問題就是有時候要做大量的分支判斷,很多人的第一反應就是使用if else。無可厚非,if else早平時做分支判斷的時候是非常好用的,但是代碼中嵌套的if/else結構往往導致代碼不美觀,也不易於理解而且性能低下。所以有時候在我們做項目的時候不可避免的一點的就是要做一些代碼的性能以及邏輯的優化。

一、簡單的邏輯判斷常用的優化方法

1.1 使用 ||

var a = 1;
if(a){
a = 1;
}else{
a = 0;
};
//可寫成
a = a || 0;

1.2 使用三元表達式

var a = 1;
var b = 2;
var c = 3;
var d = 4;
if(a == b){
a = c;
}else{
a = d;
}
//可寫成
a = (a == b) ? c : d;

1.3 按位異或運算符^

var a = 1;
var b = 2;
var c = 1;
if(a == c){
c = b;
}else if(b == c){
c = a;
};
//可寫成
c = a ^ b ^ c;

二、複雜的邏輯判斷常用的優化方法

2.1 優化if邏輯

人們考慮的東西到時候,都會把最可能發生的情況先做好準備。優化if邏輯的時候也可以這樣想:把最可能出現的條件放在前面,把最不可能出現的條件放在後面,這樣程序執行時總會按照寫的邏輯的先後順序逐一檢測所有的條件,知道發現匹配的條件才會停止繼續檢測。

if的優化目標:最小化找到分支之前所判斷條件體的數量。 if優化的方法:將最常見的條件放在首位。

var a = 1;
if(a < 10){
//代碼
}else if(a > 10 && a < 100){
//代碼
}else{
//代碼
}

以上只有在a值經常出現小於5的時候是最優化的。如果a值經常大於或者等於10的話,那麼在進入正確的分支之前,就必須兩次運算條件體,導致表達式的平均運算時間增加。if中的條件體應該總是按照從最大概率到最小概率排列,以保證理論速度最快。

2.2 switch/case

switch和if else在性能上是沒有什麼區別的,主要還是根據需求進行分析和選擇。

條件較小的話選用if else比較合適。 條件數量較大的話,就建議選用switch。 在大多數的情況下switch比if else運行的更加快。

var title = document.querySelector(h1); //h1節點對象
var txt = title.innerText; //h1節點文本內容
var dayText = ; //星期幾 對應的文本
var date = new Date(); //日期對象
var day = date.getDay(); //獲得 星期幾 0 - 6

switch (day) {
case 0:
dayText = 日;
break;
case 1:
dayText = 一;
break;
case 2:
dayText = 二;
break;
case 3:
dayText = 三;
break;
case 4:
dayText = 四;
break;
case 5:
dayText = 五;
break;
case 6:
dayText = 六;
break;
default:
break;
}
title.innerText = txt.substr(0,5)+ dayText;

上述的邏輯情況在具體的判斷選擇上,不管是代碼的優雅程度還是性能上明顯switch是比要if else要優。

2.3 數組映射

在數據查找速度方面,如果能夠直接映射到的查找方式絕對比if else判斷包括switch的性能好的太多。在js中,熟練的應用數組(包括後面提到的JSON),不管是在數據的存儲方面還是在業務邏輯的優化方面絕對是所有做前端開發者中必須套掌握的。

//用空間換取時間
var dayArr = [天,一,二,三,四,五,六];
//用day做下標 指引元素
dayText = dayArr[day];
title.innerText = txt.substr(0,5)+ dayText;

上述代碼就是通過映射的方式來查找數據,直接省去了諸多的判斷過程。

2.4 使用JSON 優化

在前後台傳輸數據的過程中,現在用的越來越多的傳輸的數據格式為JSON,第一是因為JSON是基於文本的數據格式,相對於基於二進位的數據,所以JSON在傳遞的時候是傳遞符合JSON這種格式的字元串;第二就是JSON比較輕量,即相同數據,以JSON的格式佔據的帶寬更小,這在有大量數據請求和傳遞的情況下是有明顯優勢的。

//用空間換取時間
var data = {
"0" : "日",
"1" : "一",
"2" : "二",
"3" : "三",
"4" : "四",
"5" : "五",
"6" : "六",
};
//用key做下標 指引元素
dayText = data[key];
title.innerText = txt.substr(0,5)+ dayText;

2.5 重構,用 OO 裡面的繼承或者組合

如果是喬丹,就是23
如果是科比,就是24
如果是韋德,就是3
如果是麥迪,就是1
如果都不是,就是0

來重構一下,改成OO

*定義類: 球員(或者介面)
*定義方法:就是
*定義子類:喬丹、科比、韋德、麥迪、無
*重寫方法 ---- 就是

定義一個函數,如果說是用if else:

function getNumber(name) {
if (name === "喬丹") {
console.log(23);
} else if (name === "科比") {
console.log(24);
} else if (name === "韋德"){
console.log(3);
}else if (name === "麥迪"){
console.log(1);
}else{
console.log(0);
}
}

那如果用下面的方法會更好:

function getNumber(name){
var player = {
"喬丹" : "23",
"科比" : "24",
"韋德" : "3",
"麥迪" : "1",
"無" : "0"
};
console.log(player[name] ? player[name] : player["無"] );
}

總結:其實寫代碼記住三個字即可,短簡易。代碼短,讀起來簡單,維護容易,如果在性能和代碼長度上二選一,我肯定選代碼短,性能好的。而冗長的代碼並不是加個程序員就能搞定的。 保持著這個心態寫代碼,寫出的東西離設計模式也不會差太多了。 多說一句:存在必有其價值,不能說if else多了就不好,凡事無絕對,適合A的未必就適合B,每個東西都有其實現的場景。同理改寫設計模式未必就是最棒的,聽起來高大上點而已。

推薦閱讀:

相关文章