首頁 > web前端 > js教程 > javascript for迴圈從入門到偏門(效率優化 奇特用法)_javascript技巧

javascript for迴圈從入門到偏門(效率優化 奇特用法)_javascript技巧

WBOY
發布: 2016-05-16 17:51:29
原創
1083 人瀏覽過
一,for迴圈的基本寫法
程式碼如下:
複製程式碼 程式碼如下>
//例一for(var i=1;ialert(i);
}

這段程式碼太簡單了,我都不好意思拿出手。程式碼的執行結果是依序彈出1到10,PS:在早期的IE如IE6中,你把10改成10000,就能讓用戶一直點確定什麼也不能乾了哈哈——不要說是我出的主意。
由於這是一篇基礎課程,所以我們回歸正題來詳細分析這段程式碼吧。
for迴圈的結構都是類似的,任一for迴圈都是這樣的:
for(開始前;迴圈進行的條件;迴圈一次結束後做什麼) {
// 主體程式碼
}如果仔細看for循環,就會發現他的一個萬年不變的特點:for後的()中,永遠是有且只有兩個;(英文分號)!
上面的結構程式碼已經說明,分號的作用是用來分割for迴圈的執行條件。這些條件都是缺一不可的,可以為空,但位置必須留著,所以必須有兩個;。
開始前:一般用來宣告一些變量,如例一的var i=0,就像準備了一個簍子,裡面暫時沒有任何東西。工具的數量不限,你可以在for迴圈開始前聲明100個變量,除了不好看之外,也沒什麼問題。
迴圈進行的條件:如第1個例子中的i循環一次後做什麼:例一中只是簡單的給簍子裡面加入一個東西,其實你還可以做很多事,畢竟循環一次不容易。
特別說明:for循環“開始前”的程式碼只會執行一次,不會影響整個for循環的效率,而“進行條件”與“一次結束後做什麼”,你循環次數有多少,他就執行多少次,所以他們經常成為for循環效能瓶頸。
如果說for循環第1;前是開始前做的事,那我可不可以把開始前的事情拿到for循環前面來呢?只要在開始前定義就行了嘛。答案是可以:

複製程式碼 程式碼如下:
//例2
i=0;
for(;ialert(i);
}

但要注意,雖然for後面的括號裡「開始後面的括號裡「開始前」已經沒有內容了,但;(分號)還在!而且必須在!
同理,既然第2個;後面的程式碼是一次結束後執行的,那我也可以把要執行的放在for迴圈後啊。如下:

複製程式碼 程式碼如下:
//範例3
var i= 0;
for(;ialert(i);
i
}

但依然,萬惡的兩個;還是必須存在。
上面也就是兩個基礎的「偏門用法」了。 。 。不要說我坑爹
不過你也看到了,執行循環的條件,是不能單獨提出來的,必須放在兩個分號之間!前後夾擊!

二,for迴圈的偏門寫法
1,我們把例一的程式碼變成:
var i=0;
for(;i不過這種寫法太過逆天,第2個;後面的程式碼最好不要多,一多起來你就不能掌握i的值了,而且因為程式碼混亂可能導致人為的語法錯誤。
適用環境:
簡單的for迴圈操作,例如造一個元素依序是從1到1000的數字的這麼一個數組,就用這招,酷就一個字。
2,深入分析
透過前面的例子我們知道,其實for迴圈的執行條件就是判斷一個布林值,就像這樣:

複製程式碼 程式碼如下:
var t = true;
if(t == true) {
alert('啊!')
}

這個if語句沒人看不懂吧,其實還可以這樣寫:

複製程式碼複製程式碼


複製程式碼


程式碼如下:
var t = true; if(t) { alert('啊!') }
效果是一樣的,如果for循環的進行條件就是判斷布林值,那下面這種寫法理解起來就不困難了:
複製程式碼 程式碼如下:

var i = 10;
for(;i;i--){
alert(i);
}

這段程式碼的效果是依序彈出10到1(和例一反過來了)。其中for循環的進行條件簡單的要死,就是個i.但根據我們前面的解說,其實條件是這樣的:
複製程式碼 程式碼如下:

if(i) {
//do
}

也就是i為真的狀況,就繼續執行循環。這個for迴圈的i什麼時候為真呢,只要i不等於0,空字串,undefined,null,false時,就都為真。
所以此for迴圈一直會執行,直到i=0,就結束了。但我們程式碼中不會看到0 ,迷惑新手,裝B利器。
3,又一個
先看程式碼,來自園友snandy:
複製程式碼 程式碼>
var ary = ["jack","tom","lily","andy"];
for(var i=0,a;a=ary[i ];){
console.log(a);
}

還是注意看for迴圈的進行條件:a=ary[i ]。特別注意這裡是=而不是==,要是==的話循環就沒辦法進行了。
這個條件判斷很扯,我也比較暈。類似:
if(a=b) {...} //注意是=!
此時如果b是false,那就會回傳false了。
回到上面的例子中,如果i 加出了頭,那ary[i ]就是false值了(null,undefined都算),所以條件就成了false,所以循環就斷了。
這個例子限制很大,snandy也提到了,例如你數組中就是有個0,那也可能會導致循環終結。
4,jQuery的一個寫法

複製程式碼 程式碼如下:
var r = [],
n = elem.parentNode.firstChild;
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
}
return r;
}


這是從jquery裡提取的獲得兄弟節點的辦法,他有一個奇特的for迴圈。循環進行的條件是判斷n是否為真。由於n一直是html節點,所以一直都是真。而每次循環結束後都會把n的下一個節點賦給n,而當n的下一個節點沒有時,n就成了false,終結循環。 小結:
從上面所有的例子可以看到,任他千奇百怪的for循環,都離不開兩個;。大家想看懂一個for循環的原理,直接以;為界線分割for循環即可,一目了然。

三,for迴圈的效率最佳化
1,快取變數
這也是最常用的效率最佳化方法:


複製程式碼 程式碼如下:
var arr =[1,2,23,...,1000];
for(var i=0, l = arr.length;i//
}


由於執行條件每次循環都要判斷,所以如果每次循環都從arr中讀取length的話,無疑很浪費而且必然增加計算次數,造成效率浪費。
2,倒序法
例如一個陣列有1000個元素,如果不考慮提取順序,那麼可以倒序循環:


複製程式碼複製程式碼
代碼如下:


var arr =[1,2,23,...,1000];
var i = arr.length;
for(; i>0;i--){
//alert(i);
}
為什麼倒序會比順序效率快?沒有科學道理啊!其實只是因為倒序可以少用一個變數(比較下上一個例子吧),除開這點,兩者都沒有速度差異。
3,注意跳出
不進行不必要的操作,這是基本邏輯。如有1000個li裡面,有一個li上有個特殊的className,我們要找出這個li。那麼,由於已經確定只有一個這樣的li,我們找到這個li就應該馬上跳出,break,下面的循環就沒必要進行了。這樣一來,由於li有999/1000的幾率不是最後一個,我們肯定能節省不少計算。
其他情況請舉一反三。
4,使用偏門用法
上面我介紹的偏門用法不只是寫出來好看的,大部分都有節約變數節約計算的效果,能用就用,既酷又有效,何樂而不為呢?
----------------------------總結------------------ --------------
我喜歡Javascript的靈活,不只是因為可以用來裝酷。希望在部落格園學到更多的JS知識,大牛們的文章我常常看,收益良多。以下是一些我找到的在園子裡的牛人,不全,沒有列出來者不要詛咒我。
cloudgamer,司徒正美,湯姆大叔,snandy以及其他太低調的高手。想找他們的部落格直接搜尋吧。
PS:實在是喜歡博客園的插入程式碼功能,以後涉及到大量程式碼的文章都直接發博客園吧。
不要嘗試下面的程式碼:
複製程式碼 程式碼如下:


程式碼如下:


var arr = [1,2,23,1000];
for(var i=0,l = arr.length;iif(arr[i]>10000) {
i ; } }
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板