前言
對于for循環,相信大家再常用不過了。但是這回說下for循環是因為看代碼時我居然沒有看明白一個for循環的意思,真是不應該啊。
這個for循環是這么寫的:
for (var i = 0, rule; rule = rules[i++];) { //do something}這個寫法是什么意思呢?后面再說,現賣個關子,這個寫法我感覺還是挺好的。
for循環寫法對效率的影響
說上面那段代碼之前,先說一下for循環的效率問題。在接觸js時關于for循環的寫法和對效率影響的文章挺不少的。但總的來說對于for循環的寫法有這么兩種:
for(var i = 0;i<arr.length;i++){}for(var i = 0,len = arr.length;i < len;i++){}	除了for循環還有forEach() ,也有文章說forEach()效率最高,推薦用forEach()寫法,那么到底哪個效率高呢?做個測試來看看吧。
測試方案
總的測試方案如下:
測試流程
制作測試變量
先用while循環做個測試變量出來,這個很簡單,具體如下:
var testArrs = [], i = 0;while(i<40000000){ testArrs.push(i); i++;}編寫相應測試函數
	測量和執行時間的代碼,我用的是console.time()和console.timeEnd()來進行測試。
針對這個三個for循環,先做出三個函數出來,他們分別是
foreach循環測試:
function testForeach(testArrs){ console.time('foreach'); var newArrs = []; testArrs.forEach(function(i){ newArrs.push(i); }); console.timeEnd('foreach');}沒有聲明變量的for循環:
function testNoDeclare(testArrs){ console.time('no declare'); var newArrs = []; for(var i = 0;i<testArrs.length;i++){ newArrs.push(i); } console.timeEnd('no declare');}有變量聲明的寫法
function testUseDeclare(testArrs){ console.time('use declare'); var newArrs = []; for(var i = 0,len = testArrs.length;i<len;i++){ newArrs.push(i); } console.timeEnd('use declare');}執行測試函數
執行測試函數這里很簡單啦,就是調用函數就可以了
testForeach(testArrs);testNoDeclare(testArrs);testUseDeclare(testArrs);
測試結果
經過10次測試,得到了以下結果
| foreach | 不寫聲明 | 寫聲明 | 
|---|---|---|
| 2372.891ms | 672.530ms | 743.974ms | 
| 2431.821ms | 710.275ms | 805.676ms | 
| 2422.448ms | 729.287ms | 741.014ms | 
| 2330.894ms | 730.200ms | 755.390ms | 
| 2423.186ms | 703.255ms | 769.674ms | 
| 2379.167ms | 689.811ms | 741.040ms | 
| 2372.944ms | 712.103ms | 710.524ms | 
| 2316.005ms | 726.518ms | 726.522ms | 
| 2535.289ms | 733.826ms | 747.427ms | 
| 2560.925ms | 793.680ms | 817.098ms | 
| 平均值 | 平均值 | 平均值 | 
| 2414.56ms | 720.15ms | 755.83ms | 
	不知道結果有沒有讓你出乎意料呢?沒想到最平常的寫法效率最高,為什么?我也沒想明白,誰知道就告訴我吧,但我估計寫聲明的寫法是沒有意義的。因為len = arr.length這個arr.length可能已經緩存起來了,所以我們在聲明個len變量來存儲是沒有意義的。
最后附上全部測試代碼,復制到自己的電腦上直接就可以測試了,要是有不合理的地方請告訴我吧
var testArrs = [], i = 0;while(i<40000000){ testArrs.push(i); i++;}function testForeach(testArrs){ console.time('foreach'); var newArrs = []; testArrs.forEach(function(i){ newArrs.push(i); }); console.timeEnd('foreach');}function testNoDeclare(testArrs){ console.time('no declare'); var newArrs = []; for(var i = 0;i<testArrs.length;i++){ newArrs.push(i); } console.timeEnd('no declare');}function testUseDeclare(testArrs){ console.time('use declare'); var newArrs = []; for(var i = 0,len = testArrs.length;i<len;i++){ newArrs.push(i); } console.timeEnd('use declare');}testForeach(testArrs);testNoDeclare(testArrs);testUseDeclare(testArrs);for循環的特殊寫法
下面說下文章剛開始說的那個我沒看懂的代碼,說之前先溫習下再熟悉不過的for循環語法。for循環的基本語法是:
for (語句 1; 語句 2; 語句 3){被執行的代碼塊}如果我們用for循環要輸出1到10,我們可以這么寫:
for(var i=0;i<10;i++){console.log(i);}但是!根據上面的語法說明,我們也可以寫成這樣
for(var i=10;i--;){console.log(i);}剛開始看的時候我也很疑惑,怎么能這么寫?語句2放的是循環條件,i–是什么判斷條件。其實不然,在語句2中,如果返回true循環會繼續執行。在js中0,null,undefined,false,'',””作為條件判斷時,其結果為false,也就說當i–到0的時候就是false,循環就終止了。
再回到文章開頭的代碼
for (var i = 0, rule; rule = rules[i++];) { //do something}這個rule = rules[i++]就是判斷條件,當成為undefined時就會終止循環啦。所以這段代碼換成普通寫法就是這樣的:
for(var i = 0;i < rules.length;i++){ var rule = rules[i]}其實就是把判斷和賦值放到一起了,一邊循環一邊賦值。是不是挺簡單?
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者使用Javascript能帶來一定的幫助,如果有疑問大家可以留言交流。
新聞熱點
疑難解答