Всплывающее окно, не уменьшающее массив.длину после логического оператора

#javascript #arrays #while-loop #logical-operators

#javascript #массивы #цикл while #logical-operators

Вопрос:

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

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

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

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

Ответ №1:

finalCheck в какой-то момент становится false, что приводит к тому, что data.pop() не выполняется. Затем цикл становится бесконечным.

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

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

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

Чтобы исправить свой код, вы должны, по КРАЙНЕЙ мере, использовать:

 while( data.length > 0 amp;amp; finalCheck){
    finalCheck = data.pop(); //Bye infinite loop
}
  

Комментарии:

1. спасибо, ваш ответ хорош. Это дает поведение, которого я ожидал. бьет по лбу , но я удивлен, что javascript рассматривает AND как условие в этом контексте.

2. логические операторы всегда будут действовать, ну, логично 😉 Чего вы ожидали?

Ответ №2:

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

Если вы пытаетесь дождаться, пока finalCheck не будет установлено значение true, вы, вероятно, захотите использовать || оператор вместо:

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

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

Комментарии:

1. о, я не подумал об этом, потому что я не использую оператор «И» в контексте условия. Я хочу, чтобы он оценивал два значения, используя логическое «И». Спасибо, это очень помогает. Наверное, я все еще не привык к некоторым причудам интерпретируемых языков.

2. Если вы хотите оценить обе стороны, просто выполните инструкции вне условного выражения и оцените условный оператор результатов: result = data.pop(); finalCheck = finalCheck amp;amp; resu<

Ответ №3:

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

Вы можете просто выйти из цикла, как только finalCheck станет false. Как только значение станет false, оно больше никогда не станет true, поэтому нет причин продолжать с этого момента:

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

Комментарии:

1. amp;= эквивалентно finalCheck = finalCheck amp; data.pop() , который является побитовым оператором. Этот фрагмент кода не имеет того же результата, что finalCheck = finalCheck amp;amp; data.pop() .

2. @RobW: Да, вы правы. Я удалил эту часть из ответа.