В JavaScript почему «0» равно false, но при проверке с помощью «if» оно само по себе не равно false? - PullRequest
212 голосов
/ 30 сентября 2011

Следующее показывает, что "0" является ложным в Javascript:

>>> "0" == false
true

>>> false == "0"
true

Так почему следующий текст печатает "ha"?

>>> if ("0") console.log("ha")
ha

Ответы [ 10 ]

326 голосов
/ 30 сентября 2011

Таблицы, отображающие проблему:

truthy if statement

и == truthy comparisons of all object types in javascript

Мораль использования истории === strict equality displaying sanity

кредит генерации таблицы: https://github.com/dorey/JavaScript-Equality-Table

239 голосов
/ 30 сентября 2011

Причина в том, что когда вы явно делаете "0" == false, обе стороны преобразуются в числа, и затем выполняется сравнение.

Когда вы делаете: if ("0") console.log("ha"),строковое значение проверяется.Любая непустая строка - true, а пустая строка - false.

Равен (==)

Если два операнда не одного типа , JavaScript преобразует операнды, а затем применяет строгое сравнение.Если любой из операндов равен число или логический , операнды преобразуются в числа, если это возможно;иначе, если любой операнд строка , другой операнд преобразуется в строку, если это возможно.Если оба операнда являются объектами , тогда JavaScript сравнивает внутренние ссылки, которые равны, когда операнды ссылаются на один и тот же объект в памяти.

(из Операторы сравнения в Mozilla Developer Network)

36 голосов
/ 30 сентября 2011

Это согласно спецификации.

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:

И эта таблица говорит о строках:

enter image description here

Результат равен false, если аргумент является пустой строкой (еедлина равна нулю);в противном случае результат равен true

Теперь, чтобы объяснить, почему "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, используйте === (также известный как «строгий» оператор равенства)

12 голосов
/ 30 сентября 2011

Это PHP, где строка "0" является ложной (false-when-used-in-boolean-context).В JavaScript все непустые строки являются правдивыми.

Хитрость в том, что == против логического значения не оценивается в логическом контексте, оно конвертируется в число, а в случае строк эторазбор как десятичный.Таким образом, вы получаете число 0 вместо логического значения истинности true.

Это очень плохой дизайн языка, и это одна из причин, по которой мы стараемся не использовать неудачный оператор ==.Вместо этого используйте ===.

7 голосов
/ 20 декабря 2013
// 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.
4 голосов
/ 30 сентября 2011

Ваши кавычки вокруг 0 делают его строкой, которая оценивается как true.

Удалите кавычки, и оно должно работать.

if (0) console.log("ha") 
1 голос
/ 27 октября 2018

== Оператор равенства оценивает аргументы после преобразования их в числа. Таким образом, нулевая строка «0» преобразуется в тип данных Number, а логическое ложное значение преобразуется в число 0. Итак

"0" == false // true

То жеприменяется к `

false == "0" //true

=== Строгая проверка на равенство оценивает аргументы с исходным типом данных

"0" === false // false, because "0" is a string and false is boolean

То же самое относится к

false === "0" // false

In

if("0") console.log("ha");

Строка "0" не сравнивается ни с одним аргументом, а строка является истинным значением до тех пор, пока не будет сравнено с какими-либо аргументами.Это в точности как

if(true) console.log("ha");

Но

if (0) console.log("ha"); // empty console line, because 0 is false

`

1 голос
/ 01 октября 2011

Это все из-за спецификаций 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

1 голос
/ 30 сентября 2011

Выражение «if» проверяет на правдивость, в то время как двойное равенство проверяет эквивалентность, не зависящую от типа.Строка всегда правдива, как отмечали другие.Если двойное равенство проверяет оба своих операнда на достоверность, а затем сравнивает результаты, то вы получите результат, который вы предполагаете интуитивно, т. Е. ("0" == true) === true.Как говорит Дуг Крокфорд в своем превосходном JavaScript: «Хорошие части» , «правила, по которым [== приводит типы своих операндов], сложны и не запоминаются… Отсутствие транзитивности вызывает тревогу».Достаточно сказать, что один из операндов принудительно приведен к типу, чтобы соответствовать другому, и что «0» в конечном итоге интерпретируется как числовой ноль, который в свою очередь эквивалентен ложному при приведении к логическому (или ложному эквивалентному нулю)при принуждении к числу).

0 голосов
/ 01 октября 2011
if (x) 

принуждает x, используя внутренний toBoolean JavaScript (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/

...