В JavaScript почему "0" равно false, но при проверке "if" оно не является ложным само по себе?
Ниже показано, что "0"
является ложным в Javascript:
>>> "0" == false
true
>>> false == "0"
true
Итак, почему следующая печать "ha"
?
>>> if ("0") console.log("ha")
ha
Ответы
Ответ 1
Причина в том, что, когда вы явно выполняете "0" == false
, обе стороны преобразуются в числа, а затем выполняется сравнение.
Когда вы выполните: if ("0") console.log("ha")
, проверяется строковое значение. Любая непустая строка true
, а пустая строка - false
.
Равный (==)
Если два операнда не одного типа, JavaScript преобразует операнды, а затем применяет строгое сравнение. Если любой операнд число или логическое, операнды преобразуются в числа, если это возможно; else, если любой операнд строка, другой операнд, если это возможно, преобразуется в строку. Если оба операнда являются объектами, тогда JavaScript сравнивает внутренние ссылки, равные, когда операнды ссылаются на один и тот же объект в памяти.
(Из Операторы сравнения в Mozilla Developer Network)
Ответ 2
Таблицы, отображающие проблему:
и ==
Мораль использования истории ===
кредит для создания таблицы: https://github.com/dorey/JavaScript-Equality-Table
Ответ 3
Это согласно спецификации.
12.5 The if Statement
.....
2. If ToBoolean(GetValue(exprRef)) is true, then
a. Return the result of evaluating the first Statement.
3. Else,
....
ToBoolean, согласно спецификации,
Абстрактная операция ToBoolean преобразует свой аргумент в значение типа Boolean в соответствии с таблицей 11:
И эта таблица говорит о строках:
Результат является ложным, если аргумент является пустой строкой (ее длина равна нулю); в противном случае результат будет истинным
Теперь, чтобы объяснить, почему "0" == false
вам следует прочитать оператор равенства, который утверждает, что он получает свое значение из абстрактной операции GetValue(lref)
, совпадает с тем же для правой стороны.
Что описывает эту соответствующую часть как:
if IsPropertyReference(V), then
a. If HasPrimitiveBase(V) is false, then let get be the [[Get]] internal method of base, otherwise let get
be the special [[Get]] internal method defined below.
b. Return the result of calling the get internal method using base as its this value, and passing
GetReferencedName(V) for the argument
Или, другими словами, строка имеет примитивную базу, которая вызывает внутренний метод get и заканчивает поиск false.
Если вы хотите оценить вещи, используя операцию GetValue, используйте ==
, если вы хотите оценить с помощью ToBoolean
, используйте ===
(также известный как "строгий" оператор равенства)
Ответ 4
Это PHP, где строка "0"
является ложной (false-when-used-in-boolean-context). В JavaScript все непустые строки являются правдивыми.
Фокус в том, что ==
в отношении логического значения не вычисляется в булевом контексте, он преобразуется в число, а в случае строк, выполняемых путем разбора в виде десятичного числа. Таким образом, вы получаете Number 0
вместо правды boolean true
.
Это очень плохой дизайн языка, и это одна из причин, по которым мы стараемся не использовать неудачный оператор ==
. Вместо этого используйте ===
.
Ответ 5
// I usually do this:
x = "0" ;
if (!!+x) console.log('I am true');
else console.log('I am false');
// Essentially converting string to integer and then boolean.
Ответ 6
Ваши кавычки вокруг 0
делают его строкой, которая оценивается как истина.
Удалите кавычки и он должен работать.
if (0) console.log("ha")
Ответ 7
Тесты "if" для проверки подлинности, в то время как тесты двойного равенства для независимой от типа эквивалентности. Строка всегда правдива, как указывали другие. Если двойное равенство проверяло оба его операнда для правдивости, а затем сравнивало результаты, то вы получили бы результат, который вы интуитивно принимали, т.е. ("0" == true) === true
. Как говорит Дуг Крокфорд в своем превосходном JavaScript: "Хорошие детали", правила, с помощью которых [== заставляет типы операндов] сложны и невосприимчивы... Отсутствие транзитивности вызывает тревогу ". Достаточно сказать, что один из операндов принуждается по типу, чтобы соответствовать другому, и что" 0" заканчивается интерпретацией как числовой нуль, который в свою очередь эквивалентен false при принуждении к логическому (или false эквивалентно нулю при принуждении к числу).
Ответ 8
Это все из-за спецификаций ECMA... "0" == false
из-за правил, указанных здесь http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3... И if ('0')
имеет значение true из-за правил, указанных здесь http://ecma262-5.com/ELS5_HTML.htm#Section_12.5
Ответ 9
== Оператор равенства оценивает аргументы после преобразования их в числа. Таким образом, нулевая строка "0" преобразуется в тип данных Number, а логическое false - в 0.
"0" == false//true
То же относится и к '
false == "0"//true
=== Строгая проверка на равенство оценивает аргументы с исходным типом данных
"0" === false//false, because "0" is a string and false is boolean
То же относится и к
false === "0"//false
В
if("0") console.log("ha");
Строка "0" не сравнивается ни с одним аргументом, и строка является истинным значением до тех пор, пока не будет сопоставлена с какими-либо аргументами. Это в точности как
if(true) console.log("ha");
Но
if (0) console.log("ha");//empty console line, because 0 is false
'
Ответ 10
if (x)
заставляет x использовать JavaScript внутри toBoolean (http://es5.github.com/#x9.2)
x == false
принуждает обе стороны использовать внутреннее принуждение toNumber (http://es5.github.com/#x9.3) или toPrimitive для объектов (http://es5.github.com/#x9.1)
Подробнее см. http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/