2011-07-20 41 views
1

在JavaScript程序中,我有以下兩種(簡體)函數的對象:For循環「跳到最後」沒有明顯的原因?

this.do_A = function() { 
    var nothing_changed = false; 
    while (!nothing_changed) { 
     nothing_changed = true; 
     for (var column=0; column<this.columns; column++) { 
      for (var row=0; row<this.rows; row++) { 
       nothing_changed = nothing_changed && this.do_B(row, column); 
      } 
     } 
    } 
} 

this.do_B = function(row, column) { 
    nothing_changed = true; 
    if (this[row][column] == null) { 
     nothing_changed = false; 
    } 
    return nothing_changed; 
} 

當這段代碼運行一些非常奇怪的事情發生時do_B返回false,因此nothing_changed變爲假 - 再次到達

for (var row=0; row<this.rows; row++) 

線,所述row變量變爲立即this.rows並且因此內循環終止。此外,它發生在外循環的後續運行中 - row初始化爲0,然後立即變爲this.rows並且內循環再次結束。

我沒有理由可以導致這種情況。我試圖儘可能地簡化功能,並不斷髮生。

+3

你的第一個nothing_changed是一個局部變量,你的第二個是全局變量 - 是故意的嗎? – Ariel

+0

您正在while循環的第一行將'nothing_changed'設置爲'true'。這打破了while循環中'nothing_changed'爲'false'的情況。 – Utilitron

回答

6
for (var row=0; row<this.rows; row++) 
{ 
    nothing_changed = nothing_changed && this.do_B(row, column); 
} 

this.do_B(row, column)返回falsenothing_changedfalse ,當它再次循環,併到達nothing_changed = nothing_changed && this.do_B(row, column),因爲nothing_changedfalse,第二表達this.do_B(row, column)不會被評估,因此nothing_changed總是會false直到row達到this.rows

+0

這被稱爲短路評估。 –

0

你怎麼知道for循環跳到最後?如果你通過搜索的do_B調用檢查,那麼你需要考慮的是,在下面的表達式:

nothing_changed && this.do_B(row, column) 

如果nothing_changed已經false,然後this.do_B(row, column)將不會被調用,因爲,不管是什麼RHS評估爲,表達整體將評估爲false

這就是着名的short-circuiting

也許這就是發生了什麼?如果你把調試輸出直接for循環內,我相信你會看到它繼續其指定的迭代次數結束:

for (var column=0; column<this.columns; column++) { 
    for (var row=0; row<this.rows; row++) { 
    console.log(column + "|" + row); 
    nothing_changed = nothing_changed && this.do_B(row, column); 
    } 
}