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, или, по крайней мере, это то, что я помню.
Не могли бы вы рассказать мне, что я делаю неправильно?
Ответы
Ответ 1
Алгоритм ==
(Абстрактный алгоритм сравнения равенства) не является чем-то, где вы можете просто предположить результат, если не знаете алгоритм. Вам нужно знать, как это работает.
Например, null
и undefined
- особый случай. Они не делают никакого преобразования типа, кроме того, чтобы считаться равным друг другу.
В противном случае обычно применяется преобразование типа, которое пытается свести оба операнда к общему типу. Это часто заканчивается преобразованием toNumber.
Вот почему:
Итак, если вы знаете, как работает алгоритм, вы знаете, что undefined
никогда не равняется чему-либо, кроме undefined
и null
, но другие типы, которые не являются строго равными, могут быть сведены к типам, которые равны.
Таким образом, выполнение if(!x)
vs if(x==false)
- это совершенно разные тесты.
Итак, с...
if(x == false)
... если x
- undefined
, определено, что оно не равно false
, но если x
равно 0
или даже "0"
, оно будет считаться равным false
.
-
0 == false; // true
-
"0" == false; // true
Ответ 2
undefined не равен false, но когда вы пытаетесь убедить:
if (undefined)
все выражение всегда false
Дополнительная информация: http://www.mapbender.org/JavaScript_pitfalls:_null,_false,_undefined,_NaN
Ответ 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");
}