#javascript #boolean #type-coercion
#javascript #строка #равно
Вопрос:
MDC описывает ==
оператор следующим образом:
Если два операнда не одного типа, JavaScript преобразует операнды, а затем применяет строгое сравнение. Если любой из операндов является числом или логическим значением, операнды преобразуются в числа, если это возможно; в противном случае, если любой из операндов является строкой, другой операнд преобразуется в строку, если это возможно.
Имея это в виду, я бы оценил "true" == true
следующим образом:
- Они одного типа? НЕТ
- Является ли операнд числом или логическим значением? ДА
- Можем ли мы преобразовать оба значения в число? Нет (
isNaN(Number("true")) // true
) - Является ли любой из операндов строкой? ДА
- Можем ли мы преобразовать другой операнд в строку? Да (
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 как:
- Если тип(x) — число, а тип(y) — строка,
верните результат сравнения x == ToNumber(y). - Если тип(x) — строка, а тип(y) — число,
верните результат сравнения с номером(x) == y . - Если тип(x) является логическим, верните результат сравнения ToNumber(x) == y .
- Если тип(y) является логическим, верните результат сравнения x == ToNumber(y).
Итак, «true» == true вычисляется как:
- «true» == ToNumber(true) (через правило 7)
- «true» == 1
- ToNumber(«true») == 1 (через правило 5)
- 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