乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       燮羽 2011-11-23

      如果你認(rèn)為引入Array.prototype.forEach及它的朋友會產(chǎn)生dodo那樣的for循環(huán),請?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
      }

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

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

      諷刺的是,當(dāng)高等級函數(shù)逐漸取代了老舊的傳統(tǒng)模式,我們也終于可以從舊習(xí)慣中解脫出來,去探索一些更有意思的for循環(huá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)包括四個部分:

      for (initialCode; iteratingCondition; repeatingExpression) {
          repeatingCode
      }

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

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

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

      探索它的模式

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

      常見的Array模式

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

      儲存array長度以提高效率

      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án)。當(dāng)然,只有我們可以使用逆向循環(huán)的時候,以上代碼才可用。

      在iteratingCondition中給變量賦值

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

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

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

      稀疏數(shù)列測試

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

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

      無repeatingCode部分

      repeatingCode和repeatingExpression有著相同的用途。所以如果重復(fù)代碼部分可以簡單地總結(jié)為一句代碼,你可以刪掉整個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中藏一個finally子句

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

      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án)。為保證這不會發(fā)生,你把final變量和false &&上。這會顯得有點(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來替代:

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

      在initialCode部分無變量定義

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

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

      像我之前所說,你幾乎一定會想用initialCode來給一些變量賦值,但這不是必須的。以下代碼是一個挺爛的for循環(huán),但我只是想用它來證明這一點(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)語法的變形。毫無疑問,你還會用其它一些技術(shù),我也很想聽你說說看。我并不是建議你從明天開始就急匆匆地使用所有這些模式;即使你完全不用也沒有關(guān)系!然而,舊瓶裝新酒是加強(qiáng)對一個語言深度了解的好方法,最終也會保證這個語言自身的發(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)

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多