循環是大多數程式語言都具備的基本功能,JS也不例外,不同之處在於JS是解釋型語言,運行於瀏覽器環境中,客戶端的軟硬體條件會對JS執行效率產生很大的影響。然而客戶端環境對於開發者來說是未知、多樣的,且難以改變,所以優化程式碼品質是提高程式碼效率的主要途徑。
JS程式碼中,循環是比較容易導致效能問題的因素。理解循環特性進而有針對性地進行最佳化也許會帶來不錯的效能提升。
for、while、do-while循環:
這三種循環本身的循環效率相差不多,所以只要根據適合的應用場景選擇即可。
以for迴圈為例:
var🎜> 程式碼如下:
var a🎜> ["a", "b", "c", "d"];
for(var i = 0; i fDoSomethingA(aValues[i]);
fDoSomethingA(aValues[i]);
}
上面範例中每次迴圈都要比較i與陣列的長度,所以每次都要重新讀取陣列長度,由如果數組長度在循環中是不變的,這樣做就沒有必要,我們可以使用局部變數來代替length的讀取。同理,例子中,aValues[i]由於讀取兩次以上,我們也可以將它賦值給局部變數:複製程式碼
代碼如下:
var aValues = ["a", "b", "c", "d"], nLength = aValues.length;
for(var i = 0, sValue; i sValue = aValues[i];
fDoSomethingA(sValue);
fDoSomethingB(sValue);
}如果循環的業務邏輯對循環順序不敏感,可以嘗試倒序循環,即將計數器遞減到0。
程式碼如下:
var aValues = ["a", "b", "c", "d"], nLength = aValues.length;
for(var i = nLength, sValue; i -= 1;){
sValue = aValues[i];
fDoSomethingA(sValue );
fDoSomethingB(sValue);
}
使用這種方式計數器預設與0進行比較,連局部變數比較都省略了,理論上也能提高效率。
for-in循環:
for-in循環更像在窮舉,他用來遍歷物件屬性,我們知道物件屬性的查找會一直延續到原型鏈頂端,這將大大降低循環效率。 for-in迴圈的寫法上沒有什麼優化空間,需要在使用時遵循一定原則:盡量只在遍歷資料型物件的時候才使用for-in迴圈。
如果遍歷物件的屬性是明確的,可以使用陣列循環來取代。
例如遍歷一個聯絡人物件:
程式碼如下:
程式碼如下:
var🎜 = ["N", "FN", "EMAIL;PREF", ...];
for(var i = aContact.length; i -= 1;){
fDoSomething(aContact[i]) ;
}
複製程式碼
程式碼如下:
for(var i = aValues.length; i -= 1){
fDoSomething(aValues[i]);
複製程式碼
程式碼如下:
fDoSomething(Values[ 0]);
fDoSomething(aValues[1]);
fDoSomething(aValues[2]);
fDoSomething(aValues[3]);
...
... fDoSomething(aValues[N-1]);
複製代碼 代碼如下:
var nLength = aContacts.length,
// 總輪數
nRounds = Math.floor( nLength / 8),
// 額外餘裕
nft 8,
i = 0;
// 先處理餘量
if(nLeft){
do{
fFormat(aContacts[i ]);
}while(-- }while(-- nLeft)
}
// 每輪執行8次格式化
if(nRounds){
do{
fFormat(aContacts[i ]);
fFormat(aContacts[iContacts] ]);
fFormat(aContacts[i ]);
fFormat(aContacts[i ]);
fFormat(aContacts[i ]);
fFormat(aContacts[aContacts[i ]);
fFormat(aContacts[i]);
fFormat(aContacts[i ]);
fFormat(aContacts[i ]);
}while(-- nRounds)
}
如上圖所示,每輪循環可以執行8個聯絡人資料的格式化操作,還有一輪循環用於處理剩餘的聯絡人。由此可見,在聯繫人較多的情況下總的循環次數大大降低,可以降低循環的消耗。另外,8是Duff策略提出的最優值。
實際測試時發現在IE下可以帶來10-20%以上的效能提升,而非IE瀏覽器幾乎看不到差異。 結論:在測試過程中發現非IE瀏覽器下,優化後和優化前的效率差距並不是很大,甚至可以忽略,這說明這些瀏覽器的JS引擎對