Поп не уменьшая array.length после логического оператора - PullRequest
0 голосов
/ 11 ноября 2011

У меня такое странное поведение, которого я никогда не видел и не понимаю.Я иду через массив, используя arrayname.length в качестве элемента управления для цикла while.Обычно это работает, как и ожидалось, но в данном конкретном случае создается бесконечный цикл, когда длина массива не уменьшается после первой итерации.

while( data.length > 0){
    finalCheck = finalCheck && data.pop();
}

Здесь начальная длина равна 4, а finalCheck начинается с true.Первая пара элементов массива ложна.

Как и ожидалось на первой итерации, finalCheck становится ложным, а data.length становится равным 3, но затем для каждой итерации data.length остается равным 3 ... Кто-нибудь знает, почему это произойдет?

Ответы [ 3 ]

1 голос
/ 11 ноября 2011

finalCheck становится ложным в некоторый момент, в результате чего data.pop() не выполняется. Тогда цикл становится бесконечным.

data.pop() возвращает удаленный элемент из массива. Если это значение оценивается как ложное, никакие элементы не будут удалены на следующей итерации, поэтому data.length всегда будет больше нуля.

var data = [0, 1], finalCheck = false;
while( data.length > 0){
    finalCheck = finalCheck && data.pop(); //Hello infinite loop
}

В показанном ранее примере finalCheck уже false до итерации, поэтому data.pop() никогда не будет выполнен. Даже если finalCheck инициализируется в true, finalCheck будет установлен в ноль и снова застрянет.

Чтобы исправить свой код, вы должны по крайней мере использовать:

while( data.length > 0 && finalCheck){
    finalCheck = data.pop(); //Bye infinite loop
}
1 голос
/ 11 ноября 2011

Условие в цикле использует оператор короткого замыкания &&, поэтому pop больше не будет вызываться, если finalCheck ложно.

Вы можете просто выйти из цикла, как только finalCheck станет ложным. Если оно ложно, оно никогда не станет снова правдой, поэтому нет никаких оснований для продолжения на этом этапе:

while (finalCheck && data.length > 0) {
  finalCheck = finalCheck && data.pop();
}
1 голос
/ 11 ноября 2011

Если finalCheck становится ложным, почему data.pop() когда-либо нужно выполнять? Интерпретатор JavaScript правильно закорачивает и не оценивает правую часть выражения.

Если вы пытаетесь дождаться истины finalCheck, вы, вероятно, захотите использовать вместо этого оператор ||:

finalCheck = false; // initially anyway
while( data.length > 0 && !finalCheck){
    finalCheck = finalCheck || data.pop();
}

Вам также нужно убедиться, что вы вышли из цикла, когда достигли условия завершения!

...