在我們JavaScript中, 有四種循環(huán)類型
for循環(huán)
while循環(huán)
do-while循環(huán)
for-in循環(huán)
其中前三種循環(huán)在其他語言也很常見
for-in循環(huán)對于在學(xué)校學(xué)過C/C++的同學(xué)來說也許很新鮮
它每次迭代的同時會搜索實(shí)例和原型屬性, 所以它每次迭代便會產(chǎn)生更多的開銷
for-in循環(huán)最終只有其他三種類型速度的1/7
所以, 除非我們明確需要迭代一個屬性數(shù)量未知的對象, 否則我們應(yīng)盡量避免使用for-in
更不要用for-in循環(huán)去遍歷數(shù)組
我們可以這樣去迭代一個明確的對象
var props = ['prop1', 'prop2'], i = 0;while(i < props.length){ fn(obj[props[i++]]); }
這段代碼根據(jù)對象中的屬性, 創(chuàng)建一個對象屬性的數(shù)組, 然后通過while循環(huán)來遍歷屬性列表并處理對應(yīng)屬性值
這樣就可以不用查找對象的每一個屬性, 減少了循環(huán)的開銷
上面做法的前提是對象內(nèi)部的屬性是已知的
如果我們不知道對象內(nèi)部的實(shí)現(xiàn)
還要處理對象自身的屬性,只能這樣做了
for(var prop in obj){ if(obj.hasOwnProperty(prop)){ //... } }
代價是每次迭代都要判斷這個屬性是不是對象自己的屬性而不是繼承來的
除了for-in以外, 其他的循環(huán)性能都差不多, 所以使用的時候應(yīng)該去考慮需求從而選擇循環(huán)類型
相信剛學(xué)習(xí)編程的小伙伴都是介樣寫循環(huán)的
for(var i = 0; i < arr.length; i++){ fn(arr[i]); }
這個循環(huán)語句每進(jìn)行一次迭代, 都要去查找arr中的length屬性,這樣很耗時
所以我們可以進(jìn)行優(yōu)化,
for(var i = 0, len = arr.length; i < len; i++){ fn(arr[i]); }
把數(shù)組長度值緩存到一個局部變量, 這樣問題就解決了
while, do-while也是同理
根據(jù)數(shù)組長度, 很多瀏覽器中能節(jié)省大概25%的運(yùn)行時間
我們還可以通過顛倒數(shù)組順序來略微提高性能
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--);
這樣做每次迭代控制條件從兩次判斷(迭代數(shù)是否小于總數(shù), 是否為true)
減少為一次判斷(是否為true), 進(jìn)一步提高了循環(huán)速度
最后補(bǔ)充幾句
我們大家可能都用過一些數(shù)組方法比如arr.forEach()或者一些框架的迭代方法比如jQuery的$().each()去遍歷數(shù)組,
這些方法對數(shù)組的每一個元素執(zhí)行一個函數(shù)
盡管它們很方便, 但它們要比普通的循環(huán)要慢很多(調(diào)用了外部的方法)
在所有情況下, 基于循環(huán)的迭代比基于函數(shù)的迭代快大約8倍
所以我們在能使用普通循環(huán)(for,while,do-while)解決問題的時候盡量用這些普通循環(huán)
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com