首頁  >  文章  >  web前端  >  JavaScript循環語句的效能問題

JavaScript循環語句的效能問題

黄舟
黄舟原創
2017-02-28 14:18:421376瀏覽

在大部分程式語言中, 迴圈語句消耗了大部分時間
而循環語句又是十分重要的程式模式

在我們JavaScript中, 有四種循環類型

  1. for循環

  2. while迴圈

  3. do-while迴圈

  4. for-in迴圈

其中前三種循環在其他語言也很常見
for-in循環對於在學校學過C/C++的同學來說也許很新鮮
它每次迭代的同時會搜尋實例和原型屬性, 所以它每次迭代便會產生更多的開銷
for-in循環最終只有其他三種類型速度的1/7
所以, 除非我們明確需要迭代一個屬性數量未知的物件, 否則我們應盡量避免使用for-in
更不要用for-in循環去遍歷數組

我們可以這樣去迭代一個明確的物件

var props = [&#39;prop1&#39;, &#39;prop2&#39;],      i = 0;while(i < props.length){
    fn(obj[props[i++]]);
}

這段程式碼根據物件中的屬性, 建立一個物件屬性的陣列, 然後透過while循環來遍歷屬性列表並處理對應屬性值
這樣就可以不用查找物件的每一個屬性, 減少了循環的開銷

上面做法的前提是物件內部的屬性是已知的
如果我們不知道物件內部的實作
還要處理物件本身的屬性,只能這樣做了

for(var prop in obj){    if(obj.hasOwnProperty(prop)){
        //...
    }
}

代價是每次迭代都要判斷這個屬性是不是物件自己的屬性而不是繼承來的

#除了for-in以外, 其他的循環性能都差不多, 所以使用的時候應該去考慮需求從而選擇循環類型


相信剛學習程式設計的小夥伴都是介樣寫循環的

for(var i = 0; i < arr.length; i++){
    fn(arr[i]);
}

這個循環語句每進行一次迭代, 都要去查找arr中的length屬性,這樣很耗時
所以我們可以進行優化,

for(var i = 0, len = arr.length; i < len; i++){
    fn(arr[i]);
}

把數組長度值緩存到一個局部變量, 這樣問題就解決了
while, do-while也是同理
根據數組長度, 很多瀏覽器中能節省大概25%的運行時間


我們還可以透過顛倒數組順序來略微提高性能

for(var i = items.length; i--;){
    process(items[i]);
}
var j = items.length;while(j--){
    process(items[j]);
}
var k = items.length - 1;do {
    process(items[k]);
}while(k--);

這樣做每次迭代控制條件從兩次判斷(迭代數是否小於總數, 是否為true)
減少為一次判斷(是否為true), 進一步提高了循環速度


##最後補充幾句

我們大家可能都用過一些數組方法比如arr.forEach()或者一些框架的迭代方法比如jQuery的$().each()去遍歷數組,
這些方法對數組的每一個元素執行一個函數
儘管它們很方便, 但它們要比普通的循環要慢很多(調用了外部的方法)
在所有情況下, 基於循環的迭代比基於函數的迭代快大約8倍 
所以我們在能使用普通循環(for,while,do-while)解決問題的時候盡量用這些普通循環

 以上就是JavaScript循環語句的性能問題的內容,更多相關內容請關注PHP中文網(www.php.cn)!



#

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn