使用if-else或者switch的流行理論是基於測試條件的數量:條件數量較大,傾向於使用switch而不是if-else。這通常歸結到程式碼的易讀性。
方法/步驟
一、if-else
大多數情況下switch表示式比if-else更快,但只有當條件體數量很大時才明顯更快。兩者間的主要效能區別在於:當條件體增加時,if-else 效能負擔增加的程度比switch 更多。因此,我們的自然傾向認為條件體較少時應使用if-else 而條件體較多時應使用switch 表示式,如果從效能方面考慮也是正確的。
一般來說,if-else 適用於判斷兩個離散的值或者判斷幾個不同的值域。如果判斷多於兩個離散值,switch表示式將是更理想的選擇。
二、優化if-else
優化if-else 的目標總是最小化找到正確分支之前所判斷條件體的數量。最簡單的優化方法是將最常見的條件體放在首位。
if-else中的條件體應當總是按照從最大概率到最小概率的順序排列,以保證理論執行速度最快。
三、查表法
有些情況下要避免使用if-else或switch。當有大量離散值需要測試時,if-else和switch都比使用查表法要慢得多。在JavaScript中查表法可使用陣列或者普通物件實現,查表法訪問資料比if-else或者switch更快,特別當條件體的數目很大時。
與if-else和switch相比,查表法不僅非常快,而且當需要測試的離散值數量非常大時,也有助於保持程式碼的可讀性。例如,當switch 表示式很大時就變得很笨重,諸如:
switch(value){
case 0:
return result0;
case 1:
return result1;
case 2:
return result2;
······
case 9:
return result9;
default:
return result10;
}
switch 表示式程式碼所佔的空間可能與它的重要性不成比例。整個結構可以用一個數組查表替代:
var results = [result0,······ result9, result10]
return results[value];
當使用查表法時,必須完全消除所有條件判斷。操作轉換成一個數組項查詢或者一個物件成員查詢。使用查表法的一個主要優點是:由於沒有條件判斷,當候選值數量增加時,很少,甚至沒有增加額外的效能開銷。
查表法最常用於一個鍵和一個值形成邏輯對映的領域(如前面的例子)。一個switch 表示式更適合於每個鍵需要一個獨特的動作,或者一系列動作的場合。
四、呼叫棧限制
JavaScript 引擎所支援的遞迴數量與JavaScript 呼叫棧大小直接相關。只有Internet Explorer 例外,它的呼叫棧與可用系統記憶體相關,其他瀏覽器有固定的呼叫棧限制。大多數現代瀏覽器的呼叫棧尺寸比老式瀏覽器要大(例如Safari 2 呼叫棧尺寸是100)。當你使用了太多的遞迴,超過最大呼叫棧尺寸時,瀏覽器會出錯並彈出以下資訊:
1、Internet Explorer: “Stack overflow at line x”
2、Firefox: “Too much www.heyzc.com recursion”
3、Safari: “Maximum call stack size exceeded”
4、Opera: “Abort (control stack overflow)”
Chrome 是唯一不顯示呼叫棧溢位錯誤的瀏覽器。
關於呼叫棧溢位錯誤,最令人感興趣的部分大概是:在某些瀏覽器中,他們的確是JavaScript錯誤,可以用一個try-catch表示式捕獲。異常型別因瀏覽器而不同。在Firefox中,它是一個InternalError;在Safari和Chrome中,它是一個RangeError;在Internet Explorer中丟擲一個一般性的Error 型別。(Opera不丟擲錯誤;它終止JavaScript 引擎)。這使得我們能夠在JavaScript中正確處理這些錯誤:
try {
recurse();
} catch (ex){
alert("Too much recursion!");
}
如果不管它,那麼這些錯誤將像其他錯誤一樣冒泡上傳(在Firefox中,它結束於Firebug和錯誤終端;在Safari/Chrome中它顯示在JavaScript終端上),只有Internet Explorer例外。IE 不會顯示一個JavaScript錯誤,但是會彈出一個提示堆疊溢位資訊的對話方塊。