对于循环“跳到最后”没有明显的原因?

时间:2011-07-20 12:41:58

标签: javascript for-loop

在Javascript程序中,我有一个具有以下两个(简化)函数的对象:

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变为false
for (var row=0; row<this.rows; row++)

行,row变量立即变为this.rows,因此内循环终止。此外,它发生在外循环的后续运行中 - row初始化为0,然后立即变为this.rows,内循环再次结束。

我没有理由会导致这种情况。我尽可能地简化了这些功能,并且一直在发生。

2 个答案:

答案 0 :(得分:6)

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

this.do_B(row, column)返回false时,nothing_changed将为false ,当它再次循环并到达nothing_changed = nothing_changed && this.do_B(row, column)时,由于nothing_changedfalse,第二个表达式this.do_B(row, column)将不会被评估,因此nothing_changed始终为falserow到达this.rows之前{1}}。

答案 1 :(得分: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);
  }
}