博客逐步遷移至 極客兔兔的小站javascript
上一篇隨筆介紹瞭如何正確判斷對象類型、避免變量污染,特殊值(null、undefined、NaN)的使用,以及其餘Javascript中經常使用關鍵字與方法的優化,這篇隨筆將着重介紹Javascript語言中的條件與循環優化。
若有問題,請不吝指出,很是感謝;若是喜歡,右下角點個推薦吧~html
// 方法一,假設value的值平均分佈 // 方法一的平均查詢次數是 (n+1)/2,即複雜度是O(N) // 方法二採用了二分查找,平均查找次數爲lg(n),複雜度是對數級別的 if(value === 0){ func0(); } else if (value === 1){ func1(); } else if (value === 2){ func2(); } else if (value === 3){ func3(); } else if (value === 4){ func4(); } else if (value === 5){ func5(); } else if (value === 6){ func6(); } else if (value === 7){ func7(); } // 方法二(分治策略),爲方便排版,壓縮、省略部分代碼塊 if (value < 4) { if(value < 2){ if(value === 0){ func0(); } else { func1(); } }else { if(value === 2){ func2(); } else { func3(); } } } else { // 省略同上的結構... }
如下狀況適合用switchjava
(1) 判斷值超過2個,並且值是離散的。 例如 case '男' (2) 表達式的值是固定的,不是動態變化的(3) 表達式的值值通常爲整數、字符串等類型的數據node
/* 適用狀況一:條件執行代碼不多,如使用if或switch顯得笨重 */ function func1(key){ if(key === 0){ return ans0; } if(key === 1){ return ans1; } // 省略 2,3,4,5... } // 替換爲 function func1(key){ var ans = [ans0,ans1,ans2,ans3 ... ]; return ans[key]; }
/* 適用狀況二:條件執行代碼不少,如用if或switch可讀性不好 * 同時,執行代碼可能屢次複用,並且總體性較強 * 這種寫法經常使用在javasript框架中,書寫鉤子函數(Hook) * 可讀性很高,並且容易擴展,代碼自己即文檔 */ function func1(key){ if(key === "created"){ /* ... 省略10行代碼 */ } else if(key === "init"){ /* ... 省略10行代碼 */ } // 省略 "resume","start","pause","destroy",... } // 替換爲 var hooks = { "created": function(){ /* ... 省略10行代碼 */ }; "init": function(){ /* ... 省略10行代碼 */ }; // ... 省略更多屬性 } function func1(key){ hooks[key](); }
使用&&運算時,從左到右計算表達式,一旦爲false就返回,例如:數組
A && B,若是A爲false,表達式返回false,再也不計算B。
A爲true,會繼續計算B,再決定返回值,這稱爲短路表達式
所以,若是B爲false的機率大於A,寫爲B && A能夠減小計算次數緩存
使用||運算時,一樣先計算||左側的表達式,例如:框架
A || B,若是A爲true,表達式返回true,再也不計算B。
所以,若是B爲true的機率大於A,寫爲B || A能夠減小計算次數函數
a = {} || [] // => a = {},a並無被賦值爲true,而是 {}
/* || */ var value = a || []; // 等價於 value = a ? a : []; // 等價於 if(a){ value = a; } else { value = []; } /* && */ var value = a && b; // 等價於 value = a ? b : a;
/* 當a和b均返回false時,返回一個新建對象 */ return a || b || {}; /* jQuery中大量使用短路表達式賦值 * 代碼過於簡潔,代碼可讀性會下降,適當使用 */ diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
var value = !!( a || b) // => value = true/false if(!!(a && b)) // => 顯式轉換,與if(a && b)結果一致
items = [1,2,3]; items.forEach(function(value,index,array) { // ... func(value); }) // 等價於 var len = items.length; for(var i = 0; i < len; ++i ){ // ... func(items[i]); }
len
,若是不使用變量len暫存,那麼每次循環都須要訪問數組的length
屬性,比起直接訪問一個數字,訪問一個對象屬性的花銷會更大。// 暫存變量前,獲取 p#item,須要3次DOM操做, $('p#item').func1(); $('p#item').func2(); $('p#item').func3(); // 等價於(這裏不考慮jQuery的鏈式操做) // 只須要一次DOM操做(DOM操做很是耗時) var p_item = $('p#item'); p_item.fun1(); // ...
/* 不暫存變量 */ var obj = { nickname:{} }; obj['nickname'].firstname = 'Tom'; obj['nickname'].lastname = 'Smith'; obj['nickname'].fullname = 'Tom Smith'; // 壓縮結果 var a = { nickname:{} }; a['nickname'].firstname = 'Tom'; a['nickname'].lastname = 'Smith'; a['nickname'].fullname = 'Tom Smith'; /* 暫存變量 */ var obj = { nickname:{} }; var nickname = obj['nickname']; nickname.firstname = 'Tom'; nickname.lastname = 'Smith'; nickname.fullname = 'Tom Smith'; // 壓縮結果以下 var a = { nickname:{} }; var b = a['nickname']; b.firstname = 'Tom'; b.lastname = 'Smith'; b.fullname = 'Tom Smith';
分享創造價值,喜歡這個系列文章,不妨關注一下~性能