Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

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

>>> "0" == false
true

>>> false == "0"
true

Так 9X_boolean почему же следующий вывод "ha"?

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

267
6

  • @Linsey: Вся эта штука с «ложью» и «правдой» была предназначена только для того, чтобы объяснить, как значения преобразуются в логические значения. Когда вы срав ...
11
Общее количество ответов: 11

Ответ #1

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Таблицы, в которых отображается проблема:

9X_Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?_ecmascript

и 9X_vanilla-js == 9X_Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?_boolean

Мораль использования рассказа === 9X_Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?_javascript

Кредит 9X_boolean-expression на создание таблицы: https://github.com/dorey/JavaScript-Equality-Table

398
4

  • В этих таблицах есть ошибка. Ни `==`, ни `===` для значений `[]`, ...

Ответ #2

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Причина в том, что при явном выполнении 9X_javascript-execution "0" == false обе стороны преобразуются в числа, и затем выполняется 9X_vanillajs сравнение.

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

Равно (==)

Если два 9X_javascript-dom операнда не одного типа, JavaScript преобразует операнды, а 9X_vanilla-javascript затем применяет строгое сравнение. Если 9X_ecmascript один из операндов - число или логическое значение, операнды по возможности 9X_javascript-library преобразуются в числа; иначе, если один 9X_ecmascript из операндов является строкой, другой операнд преобразуется 9X_bool в строку, если это возможно. Если оба операнда являются объектами, тогда 9X_javascript-execution JavaScript сравнивает внутренние ссылки, которые 9X_vanillajs равны, когда операнды ссылаются на один 9X_vanilla-js и тот же объект в памяти.

(Из Comparison Operators в сети разработчиков 9X_js Mozilla)

283
0

Ответ #3

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

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

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, согласно 9X_boolean-expression спецификации,

Абстрактная операция ToBoolean 9X_ecmascript преобразует свой аргумент в значение типа 9X_vanillajs Boolean в соответствии с таблицей 11:

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

9X_Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?_javascript-dom

Результат будет 9X_javascript-library ложным, если аргумент - пустая строка (ее 9X_bool длина равна нулю); в противном случае 9X_vanilla-js результат верный

Теперь, чтобы объяснить, почему 9X_javascript "0" == false вы должны прочитать оператор равенства, в 9X_javascript котором говорится, что он получает свое 9X_.js значение из абстрактной операции, GetValue(lref) совпадает 9X_javascript с тем же для правой стороны.

Что описывает 9X_javascript-dom эту соответствующую часть как:

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

Или, другими 9X_javascript словами, строка имеет примитивную базу, которая 9X_vanilla-js вызывает внутренний метод get и в конечном 9X_vanilla-javascript итоге выглядит ложным.

Если вы хотите оценить 9X_javascript-dom вещи с помощью операции GetValue, используйте 9X_vanilla-js ==, если вы хотите оценить с помощью ToBoolean, используйте 9X_javascript === (также известный как «строгий» оператор 9X_boolean равенства)

41
1

  • Где я могу найти спецификацию?<p><span clas ...

Ответ #4

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

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

Хитрость заключается в том, что 9X_javascript == для логического значения не вычисляется 9X_bool в логическом контексте, он преобразуется 9X_bool в число, а в случае строк это выполняется 9X_javascript-execution путем синтаксического анализа как десятичного. Таким 9X_javascript образом, вы получаете число 0 вместо логического 9X_javascript значения истинности true.

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

13
0

Ответ #5

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

// 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.

9X_bool

8
0

Ответ #6

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Ваши кавычки вокруг 0 превращают его в строку, которая 9X_vanilla-js оценивается как истинная.

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

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

6
1

  • правильно, не о том, как «заставить его работать», а вопрос ...

Ответ #7

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Это все из-за спецификаций ECMA ... "0" == false из-за 9X_javascript правил, указанных здесь http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3 ... И if ('0') оценивается 9X_javascript-dom как истина из-за правил, указанных здесь 9X_boolean-expression http://ecma262-5.com/ELS5_HTML.htm#Section_12.5

2
0

Ответ #8

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

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

"0" == false // true

То 9X_boolean-expression же самое относится к `

false == "0" //true

=== При строгой проверке 9X_vanilla-js равенства аргументы оцениваются с исходным 9X_boolean-expression типом данных

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

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

false === "0" // false

В

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

Строка 9X_vanilla-js «0» не сравнивается ни с какими аргументами, а 9X_vanilla-javascript строка является истинным значением до тех 9X_.js пор, пока она не сравнивается с какими-либо 9X_vanilla-javascript аргументами. Это в точности как

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

Но

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

`

2
0

Ответ #9

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

По этой причине вы должны по возможности 9X_javascript использовать строгое равенство === или строгое 9X_javascript-execution неравенство !==

"100" == 100

true, потому что при этом проверяется 9X_vanillajs только значение, а не тип данных

"100" === 100

false проверяет 9X_javascript значение и тип данных

2
0

Ответ #10

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Выражение «if» проверяет истинность, а выражение 9X_boolean двойного равенства проверяет эквивалентность, независимую 9X_javascript-dom от типа. Строка всегда правдива, как указывали 9X_bool здесь другие. Если бы двойное равенство 9X_vanillajs проверяло оба своих операнда на истинность, а 9X_boolean-expression затем сравнивало результаты, то вы бы получили 9X_vanillajs результат, который интуитивно предполагали, то 9X_boolean-expression есть ("0" == true) === true. Как говорит Дуг Крокфорд в своем 9X_vanilla-javascript превосходном JavaScript: хорошие части, «правила, по которым [== приводит 9X_javascript к типам своих операндов], сложны и не запоминаются 9X_vanilla-js ... Отсутствие транзитивности вызывает тревогу. " Достаточно 9X_ecmascript сказать, что один из операндов приводится 9X_js к типу, чтобы соответствовать другому, и 9X_javascript что "0" в конечном итоге интерпретируется 9X_boolean-expression как числовой ноль, который, в свою очередь, эквивалентен 9X_javascript-library false при принуждении к логическому (или 9X_vanilla-javascript false эквивалентно нулю) при принуждении 9X_javascript к номеру).

1
0

Ответ #11

Ответ на вопрос: Почему в JavaScript «0» равно false, но при проверке с помощью if оно не является ложным само по себе?

Это связано с тем, что JavaScript использует 9X_js приведение типов в логических контекстах 9X_bool и ​​в вашем коде

if ("0") 

будет принудительно присвоено 9X_javascript-execution значение true в логических контекстах.

В 9X_boolean Javascript есть и другие истинные значения, которые 9X_js будут принудительно установлены в true в 9X_vanilla-js логических контекстах и, таким образом, выполнят 9X_javascript-dom блок if: -

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

1
0