2011-07-20 40 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); 
    } 
}