Почему «true» == true показывает false в JavaScript?

#javascript #boolean #type-coercion

#javascript #строка #равно

Вопрос:

MDC описывает == оператор следующим образом:

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

Имея это в виду, я бы оценил "true" == true следующим образом:

  1. Они одного типа? НЕТ
  2. Является ли операнд числом или логическим значением? ДА
  3. Можем ли мы преобразовать оба значения в число? Нет ( isNaN(Number("true")) // true )
  4. Является ли любой из операндов строкой? ДА
  5. Можем ли мы преобразовать другой операнд в строку? Да ( String(true) === "true" // true )

В итоге я получил строки "true" и "true" , которые должны быть равны true , но JavaScript показывает false.

Что я пропустил?

Комментарии:

1. Уместно: es5.github.com/#x11.9.1

2. С таким большим количеством JavaScript мир — страшное место: if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")} —> «нет, да»

3. Я должен сказать, я удивлен, и это ооочень глупо, что это происходит. Еще одна причина всегда всегда использовать ===

4. @user1068352 проверь хаос 🙂 dorey.github.io/JavaScript-Equality-Table

Ответ №1:

Потому что "true" преобразуется в NaN , в то время как true преобразуется в 1 . Итак, они отличаются.

Как вы сообщали, оба преобразуются в числа, потому что, по крайней мере, true может быть (см. Комментарий Эрика Реппена), а затем сравниваются.

Комментарии:

1. Можете ли вы сказать мне, когда шаг Can we convert both to a number? будет когда-либо false тогда? Если четное NaN является числом, как этот шаг может когда-либо завершиться неудачей?

2. Либо или ни то, ни другое. Если оба приведут к NaN, они переключатся на вычисление строки. Если только один может быть преобразован, все равно есть сравнение чисел.

3. На самом деле в Javascript есть несколько странных объектов, которые ведут себя довольно странно. Например, XML-документы в IE<9 выдают ошибку при попытке преобразовать их в числа.

4. Вы можете сами увидеть преобразования, выполнив Number(true) и Number('true')

Ответ №2:

== Оператор сравнения определен в ECMA 5 как:

  1. Если тип(x) — число, а тип(y) — строка,
    верните результат сравнения x == ToNumber(y).
  2. Если тип(x) — строка, а тип(y) — число,
    верните результат сравнения с номером(x) == y .
  3. Если тип(x) является логическим, верните результат сравнения ToNumber(x) == y .
  4. Если тип(y) является логическим, верните результат сравнения x == ToNumber(y).

Итак, «true» == true вычисляется как:

  1. «true» == ToNumber(true) (через правило 7)
  2. «true» == 1
  3. ToNumber(«true») == 1 (через правило 5)
  4. NaN == 1

===> false

Ответ №3:

В соответствии с абстрактным алгоритмом сравнения равенства

http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

если одно из значений является логическим, а другое нет, значение boolean преобразуется в число 0 или 1. таким образом, true == "true" равно false.

Комментарии:

1. Правильно ли я сделал следующий вывод? «true» == true становится «true» == 1, а затем становится «true» == «1» Вот почему они возвращают false?

Ответ №4:

Операторы равенства ( == и != ) используют абстрактный алгоритм сравнения равенства для сравнения двух операндов.

"true" == true

Поскольку "true" есть String и true является Boolean , нам нужно вернуть результат "true" == Number(true) (шаг 7 алгоритма), который является "true" == 1 .

"true" == 1

Поскольку "true" есть String и 1 является Number , нам нужно вернуть результат Number("true") == 1 (шаг 5 алгоритма). Number("true") ВОЗВРАТ NaN . Теперь у нас есть NaN == 1 .

NaN == 1

Теперь оба операнда имеют один и тот же тип ( Number ). В соответствии с алгоритмом, если оба операнда являются Number и один из них является NaN , false возвращается (шаг 1.c.i алгоритма).

Ответ №5:

Объяснение с учетом сценария true == «истина».
Сразу же, приведенное выше возвращает false, однако наше ожидание было верным
JavaScript использует абстрактный алгоритм сравнения равенства, поэтому в соответствии с алгоритмом

 true == "true"

// If one of the operands is Boolean, convert the Boolean operand to 1 if it is true and  0 if it is false
ConvertToNumber(true) == "true"

1 == "true"

// When the algorithm finds the above statements, it thinks that it needs to do one more conversion - 
// "When comparing a number to a string, try to convert the string to a numeric value"
1 == ConvertToNumber("true)
1 == NaN

// Which returns false