Подтвердить что ты не робот

Undefined переменные, value == false versus! value

У меня проблема с очень простой частью кода, написанной в Javascript, не могли бы вы мне помочь?

Вот что я думаю, что до сих пор понял javascript и переменные:

  • Значение undefined оценивается как false в логической операции
  • Используя оператор == в сравнении, вы спрашиваете, сопоставимы ли два значения независимо от их типов.

Я нашел файл упражнений в онлайн-курсе, и я попытался это сделать, но у меня не было такого же результата, ожидаемого на уроке; основная проблема заключалась в том, что я сравнивал значение через значение "if value == false {...}", в то время как в решении использовалось значение "if! value {...}"

Поэтому я решил написать очень короткий код, чтобы попробовать его сам, но я получаю смешанные результаты. Здесь, в приведенном ниже примере, я ожидал бы, что этот JS-код сгенерирует два одинаковых предупреждения ( "foo равно false" ), но вместо этого первый оператор if возвращает "foo IS NOT равно false", а второй - возвращает (как и ожидалось) "foo равно false".

Вот что я написал:

var foo = undefined;

if (foo == false) {
  alert("foo is equal to false");
} else {
  alert("foo is not equal to false"); // Javascript executes this row
}

if (!foo) {
  alert("foo is equal to false");  // Javascript executes this row
} else {
  alert("foo is not equal to false");
}

AFAIK, оба IF должны выполнять одну и ту же работу и вводить, когда я его пробовал, заменив в первой строке значение "var foo = undefined;" с "var foo = 0;" он работал как ожидалось, а 0 - другое значение, которое должно быть оценено как false, или, по крайней мере, это то, что я помню.

Не могли бы вы рассказать мне, что я делаю неправильно?

4b9b3361

Ответ 1

Алгоритм == (Абстрактный алгоритм сравнения равенства) не является чем-то, где вы можете просто предположить результат, если не знаете алгоритм. Вам нужно знать, как это работает.

Например, null и undefined - особый случай. Они не делают никакого преобразования типа, кроме того, чтобы считаться равным друг другу.

В противном случае обычно применяется преобразование типа, которое пытается свести оба операнда к общему типу. Это часто заканчивается преобразованием toNumber.

Вот почему:

  • null == undefined; // true

  • null == 0; // false

  • +null == '0' // true

Итак, если вы знаете, как работает алгоритм, вы знаете, что undefined никогда не равняется чему-либо, кроме undefined и null, но другие типы, которые не являются строго равными, могут быть сведены к типам, которые равны.

Таким образом, выполнение if(!x) vs if(x==false) - это совершенно разные тесты.

  • if(!x) выполняет toBoolean-преобразование.

  • if(x == false) использует сложный алгоритм для принятия правильного преобразования.

Итак, с...

if(x == false)

... если x - undefined, определено, что оно не равно false, но если x равно 0 или даже "0", оно будет считаться равным false.

  • 0 == false; // true

  • "0" == false; // true

Ответ 3

Истина и эквивалентность с true - это две разные вещи в JavaScript.

if (...) выполняет первый оператор, если ... является " правдой", а не когда он "равен" любому другому конкретному значению, поэтому ваше второе условие должно выглядеть как

if (!foo) {
  alert("foo is falsy");  // Javascript executes this row
} else {
  alert("foo is truthy");
}

В JavaScript существует немало "ложных" значений: NaN, "", 0, -0, false, null, undefined. Все остальные значения truthy.

Оператор ! возвращает false для любого правдивого значения и true для любого значения falsy, поэтому !x совпадает с (x ? false : true) для всех x.

Ответ 4

Как правило, я считаю, что положительный результат легче анализировать, почти так, как если бы if(!foo) был двойным отрицательным, поэтому я бы повернул его вокруг:

if (foo) {
  alert("foo is something or boolean true");
} else {
  alert("foo is null, undefined or boolean false");
}

В частности, оба undefined и null не являются истинными или ложными, но javascript может обрабатывать своего рода стенографию, потому что она динамическая.

В действительности вышеприведенное утверждение выглядит примерно так:

if (foo != null && (foo.constructor !== Boolean || foo == true)) {
  alert("foo is something or boolean true");
} else {
  alert("foo is null, undefined or boolean false");
}

Сначала вы проверяете, что переменная определена, а затем, если она является логической, что она истинна.

Между тем ваше ложное утверждение проверяет что-то другое:

if (foo == false) {
  alert("foo is populated with the boolean false");
} else {
  alert("foo is true, something else or null");
}