小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

JavaScript之for循環(huán)重思

 燮羽 2011-11-23

如果你認(rèn)為引入Array.prototype.forEach及它的朋友會(huì)產(chǎn)生dodo那樣的for循環(huán),請(qǐng)?jiān)傧胂?。for循環(huán)老當(dāng)益壯。

For循環(huán)經(jīng)常被當(dāng)作一只搗蛋的小馬駒(難以馴服—譯者按)。它最適合于解決經(jīng)典的重復(fù)列舉問題:

for (var i=0; i<=arr.length-1; i++) {
    //do something to each member
}

但隨著更高等級(jí)命令函數(shù)的出現(xiàn),無(wú)論是在本地程序還是在架構(gòu)中,我們都可以寫以下代碼(或類似變異)

arr.forEach(function(each)) {
    //do something to each
});

諷刺的是,當(dāng)高等級(jí)函數(shù)逐漸取代了老舊的傳統(tǒng)模式,我們也終于可以從舊習(xí)慣中解脫出來(lái),去探索一些更有意思的for循環(huán)模式。

開胃菜——這是一個(gè)超級(jí)簡(jiǎn)潔的方法去生成并顯示出斐波那契數(shù)列中的前n位:

for (
    var i=2, r=[0,1];
    i<15 || alert(r);
    r.push(r[i-1] + r[i-2]), i++
);
//alerts "0,1,1,2,3,5,8,13,21,34,55,89,144,233,377"

 

基礎(chǔ)

For循環(huán)的結(jié)構(gòu)包括四個(gè)部分:

for (initialCode; iteratingCondition; repeatingExpression) {
    repeatingCode
}

- 所有4個(gè)部分都是非必要的。
-initialCode不需要被賦一個(gè)變量—任何有效的表達(dá)式都可以。
-iteratingCondition和repeatingExpression不能包含變量定義。
-當(dāng)repeatingCode為空或只有一句,花括號(hào)就不是必要的。
當(dāng)repeatingCode部分被執(zhí)行后,repeatingExpression會(huì)被再次估值。

我們可以用偽代碼的方式總結(jié)整個(gè)過程——(函數(shù)調(diào)用部分單純是為了易讀性)

initialCode();
while(iteratingCondition()) {
	repeatingCode();
	repeatingExpression();
}

探索它的模式

在這一章里,for循環(huán)的用法會(huì)從我們熟悉的樣子變得有點(diǎn)古怪。這樣做的意圖是向你展示結(jié)構(gòu)的多變和語(yǔ)句的力量。我并不是為了給你提供最好的練習(xí)范本。

常見的Array模式

for (var i=0; i<=arr.length-1; i++) {
    var member = arr[i];
    doSomething(member);
}

儲(chǔ)存array長(zhǎng)度以提高效率

for (var i=0, l=arr.length; i<=l-1; i++) {
    var member = arr[i];
    doSomething(member);
}

合并iteratingCondition和repeatingExpression

for (var i=arr.length; i--;) {
    var member = arr[i];
    doSomething(member);
}

這樣做的原理是當(dāng)i為0, 判定條件變?yōu)閒alse,我們會(huì)退出循環(huán)。當(dāng)然,只有我們可以使用逆向循環(huán)的時(shí)候,以上代碼才可用。

在iteratingCondition中給變量賦值

我們可以把repeatingCode中的變量賦值移到theriteratingCondition中去。當(dāng)each無(wú)定義時(shí),循環(huán)就會(huì)被終止。

這樣我們就縮短了代碼的長(zhǎng)度并且不需要檢查數(shù)列長(zhǎng)度。語(yǔ)法變得更直接,在我看來(lái),也更優(yōu)雅。只有當(dāng)數(shù)列是連續(xù)的,并且不會(huì)有出現(xiàn)“falsey”值(null,0,空或false)的時(shí)候,這個(gè)方法才可用。

for (var i=0, each; each = arr[i]; i++) {
    doSomething(each);
}

稀疏數(shù)列測(cè)試

我們可以倒轉(zhuǎn)以上的模式來(lái)主動(dòng)地檢查一個(gè)稀疏的數(shù)列或列表。這里我們高效地檢測(cè)未定義參數(shù):

var func = function(a,b,c) {
    for (var i=0; arguments[i] !== undefined; i++);
    var allArguments = (i >= arguments.callee.length);
    //...
}

無(wú)repeatingCode部分

repeatingCode和repeatingExpression有著相同的用途。所以如果重復(fù)代碼部分可以簡(jiǎn)單地總結(jié)為一句代碼,你可以刪掉整個(gè)repeatCode部分。

function sum(arr) {
	for (var i=arr.length, r=0; i--; r += arr[i]);
	return r;
}

sum([3,5,0,-2,7,8]); //21

在iteratingCondition中藏一個(gè)finally子句

我們可以使用 邏輯布爾值||運(yùn)算符 來(lái)定義一個(gè)final語(yǔ)句。這個(gè)小函數(shù)會(huì)把一個(gè)數(shù)組中的值相加,并在完成后打印出這個(gè)值。

function shoutOutSum(arr, x) {
	for (var i=arr.length, r=0; i-- || alert(r); r += arr[i]);
}

shoutOutSum([3,5,0,-2,7,8]); //alerts "21"

當(dāng)然如果你的最終子句不返回falsey值的話,你就有麻煩了。你會(huì)陷入死循環(huán)。為保證這不會(huì)發(fā)生,你把final變量和false &&上。這會(huì)顯得有點(diǎn)笨拙:

function sumAndMultiply(arr, x) {
	for (var i=arr.length, r=0; i-- || ((r = r*x) && false); r += arr[i]);
	return r;
}
sumAndMultiply([3,5,0,-2,7,8], 5); //105

更新:Brendan Eich建議用void來(lái)替代:

function sumAndMultiply(arr, x) {
        for (var i=arr.length, r=0; i-- || void (r = r*x); r += arr[i]);
	return r;
}

在initialCode部分無(wú)變量定義

initialCode不需要變量定義。為了不因variable hoisting產(chǎn)生混淆,很多程序員在函數(shù)的開頭定義所有變量,有些JavaScript專家(包括Douglas Crockford)甚至不會(huì)再for循環(huán)中定義變量。

function myFunction(arr) {
	var i;
	//...
	for (i=0; i < arr.length; i++) {
		//...
	}
	//...
}

像我之前所說(shuō),你幾乎一定會(huì)想用initialCode來(lái)給一些變量賦值,但這不是必須的。以下代碼是一個(gè)挺爛的for循環(huán),但我只是想用它來(lái)證明這一點(diǎn)。

var i = 0;
for (
    console.log('start:',+new Date);
    i<1000 || console.log('finish:',+new Date);
    i++
);

總結(jié)

本文只是列舉了幾種傳統(tǒng)for循環(huán)語(yǔ)法的變形。毫無(wú)疑問,你還會(huì)用其它一些技術(shù),我也很想聽你說(shuō)說(shuō)看。我并不是建議你從明天開始就急匆匆地使用所有這些模式;即使你完全不用也沒有關(guān)系!然而,舊瓶裝新酒是加強(qiáng)對(duì)一個(gè)語(yǔ)言深度了解的好方法,最終也會(huì)保證這個(gè)語(yǔ)言自身的發(fā)展和成功。

繼續(xù)閱讀

ECMA-262, 5th edition
section 12.6.3 (The for statement)
sections 15.4.4.14 to 15.4.4.22 (High OrderArray Functions)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多