Для цикла «прыгает до конца» без видимой причины? - PullRequest
1 голос
/ 20 июля 2011

В программе 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 ]

6 голосов
/ 20 июля 2011
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_changed равно false, второе выражение this.do_B(row, column) не будет оцениваться, поэтому nothing_changed всегда будет false, пока row не достигнет this.rows .

0 голосов
/ 20 июля 2011

Откуда вы знаете, что цикл for прыгает до конца?Если вы проверяете путем поиска вызовов do_B, то вам необходимо учитывать тот факт, что в следующем выражении:

nothing_changed && this.do_B(row, column)

, если nothing_changed уже false, то this.do_B(row, column) не будет вызываться, потому что, независимо от того, к чему относится RHS, выражение в целом оценивается как false.

Это известно как короткое замыкание .

Возможно, это то, что происходит?Если вы поместите выходные данные отладки непосредственно в цикл 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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...