2015-04-16 57 views
0

我在Codepen的一個特定for循環的執行順序中有點難以置信。看看這兩個循環,這都做同樣的事情:JavaScript for循環執行的確切順序是什麼?

var a = ['orange','apple']; 
for (var i=0; i<2;i++) { 
    alert(a[i]); 
} 

for (var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

您可以在這裏的行動看到這一點:http://codepen.io/nickbarry/pen/MYNzLP/

第一個循環是寫一個for循環的標準,香草方式。正如預期的那樣,它會提醒「橙色」,然後是「蘋果」。

我寫了第二個循環使用MDN的建議(搜索「成語」,這裏:https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。

它的工作原理,但我不明白爲什麼。我對for循環的理解顯然是不正確的(不止一種方式): * for循環在第一次運行之前評估第二個表達式的真實性。所以,當for循環正在評估第二個表達式的真實性時,它似乎應該在設置水果的值之前增加j。所以第一次通過循環,水果應該等於「蘋果」。 *循環只能運行一次,因爲在第一次通過後,當它再次計算第二個表達式以查看它是否仍然爲真時,它應該再次遞增j,然後它將值返回給果實,並且由於沒有值在索引位置2時,它應該返回一個虛假結果,並退出循環。

我不明白究竟發生了什麼。 for循環在第二個表達式計算之前運行一次嗎?但這似乎是不可能的,因爲如果發生這種情況,警報將在第一次通過時沒有提醒,因爲水果還沒有價值。

此外,MDN文章的作者似乎喜歡寫循環的第二種方式 - 有沒有一個原因,方式更好?它使用較少的字符,這是很好的,我猜。跳過for循環中的第三個表達式可以節省大量時間嗎?或者它只是一個「很酷,因爲它很聰明」的東西?

+1

它工作的原因是它是一個後增量,而不是預增量。如果它是'++ j'而不是'j ++',那麼你的假設是真實的。 –

+1

如果你的目標是製造敵人,編寫循環的第二種方法非常好。沒有真正的好處,它很難閱讀,如果數組中存在虛假值並且可能較慢(儘管測試需要確定),它會過早停止。 –

+1

請注意,MDN是一個wiki。任何半智慧都可以添加內容。同一篇文章實際上暗示了數組的「for-in」,但沒有給出所有可能遇到的問題的完整解釋。 –

回答

5
for (var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

僞代碼等於:

initialize j = 0 and fruit = undefined 

assign fruit = a[j] (j = 0, fruit = 'orange') 
j = j + 1 (j = 1) 
check fruit for being truthy (true) 

alert(fruit) ('orange') 

assign fruit = a[j] (j = 1, fruit = 'apple') 
j = j + 1 (j = 2) 
check fruit for being truthy (true) 

alert(fruit) ('apple') 

assign fruit = a[j] (j = 2, fruit = undefined) 
j = j + 1 (j = 3) 
check fruit for being truthy (false) 

exit loop 

重要提示:

後綴一元++操作符爲:

  1. 我們返回的的電流值變量
  2. 我們增加變量

的值是否跳過了第三個表達式循環節省顯著的時間?

它不會在所有

而且保存任何的MDN文章的作者似乎喜歡寫循環的第二種方式 - 有一個原因,方式是更好?

這在任何方面都不會更好。作者只是認爲它很酷,作者喜歡酷(而他們不是)。

+0

謝謝,這正是我需要的答案! –

0

for循環實際上只是寫一個while循環的簡寫方式。 例如這個循環

for(var i = 0, j = 10; i < 10; i++, j++) { 
    alert(i + ", " + j); 
} 

只是一個寫

var i = 0, j = 10; 
while(i < 10) { 
    alert(i + ", " + j); 
    i++; j++; 
} 

讓芒這個循環較短方式

for(var j=0, fruit; fruit = a[j++];) { 
    alert(fruit); 
} 

是一樣的,因爲這

var j = 0, fruit; 
while(fruit = a[j++]) { 
    alert(fruit); 
} 
0

您可以按照通過執行JavaS的順序cript的for循環使用SlowmoJS:http://toolness.github.io/slowmo-js/

該主頁已將for循環加載到控制檯用於演示目的,但您可以根據需要評估任何代碼的操作順序。