Reputation: 3539
In a Javascript program I have an object with the following two (simplified) functions:
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;
}
When running this code something very strange happens when do_B returns false, and hence nothing_changed becomes false - when reaching again the
for (var row=0; row<this.rows; row++)
line, the row
variable becomes immediately this.rows
and hence the inner loop terminates. Moreover, it happens in the subsequent runs of the outer loops - row
is initialized to be 0
, then becomes this.rows
immediately and the inner loop ends again.
I have no reason what can cause this. I have tried simplifying the functions as much as possible and it keeps happening.
Upvotes: 1
Views: 435
Reputation: 35730
for (var row=0; row<this.rows; row++)
{
nothing_changed = nothing_changed && this.do_B(row, column);
}
When this.do_B(row, column)
returns false
, nothing_changed
will be false
, and when it loops again and reaches nothing_changed = nothing_changed && this.do_B(row, column)
, because nothing_changed
is false
, the second expression this.do_B(row, column)
will not be evaluated, so nothing_changed
will always be false
until row
reaches this.rows
.
Upvotes: 6
Reputation: 385194
How do you know the for
loop jumps to the end? If you're checking by searching for invocations of do_B
, then you need to account for the fact that in the following expression:
nothing_changed && this.do_B(row, column)
if nothing_changed
is already false
, then this.do_B(row, column)
will not be called because, no matter what the RHS evaluates to, the expression as a whole will evaluate to false
.
This is known as short-circuiting.
Perhaps that's what's going on? If you put debug output directly inside the for
loop, I'm sure you'll see it continuing to the end of its prescribed number of iterations:
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);
}
}
Upvotes: 0