Почему 1 == 1 == 1 возвращает true, "1" == "1" == "1" возвращает true, а "a" == "a" == "a" возвращает false?
function a() { return (1 == 1 == 1); }
function b() { return ("1" == "1" == "1"); }
function c() { return ("a" == "a" == "a"); }
Я тестировал вышеуказанный код в консоли Chrome, и по какой-то причине a()
возвращает true, b()
возвращает true, а c()
возвращает false.
Почему это так?
Ответы
Ответ 1
Потому что вы сравниваете (логический) результат первого равенства с (небулевым) третьим значением.
В коде 1 == 1 == 1
эквивалентен (1 == 1) == 1
эквивалентен true == 1
.
Это означает, что три метода можно записать проще:
function a() { return (true == 1); }
function b() { return (true == "1"); }
function c() { return (true == "a"); }
Эти сравнения работают в соответствии с этими правилами (внимание мое):
Если два операнда не одного типа, JavaScript преобразует операндов, затем применяет строгое сравнение. Если либо операнд является number или boolean, операнды преобразуются в числа, если возможно; else, если любой операнд является строкой, операнд строки если возможно, преобразуется в число. Если оба операнда являются объектами, то JavaScript сравнивает внутренние ссылки, которые равны при использовании операндов обратитесь к одному и тому же объекту в памяти.
Итак, что происходит в c
, так это то, что "a"
преобразуется в число (давая NaN
), и результат строго сравнивается с true
, преобразованным в число (давая 1
).
Так как 1 === NaN
есть false
, третья функция возвращает false
. Очень легко понять, почему первые две функции вернут true
.
Ответ 2
Потому что 1 == true
Но "a" != true
Итак, в основном происходит то, что
1 == 1
, "1" == "1"
и "a" == "a"
оцениваются как true
, а затем сравниваются со следующим значением.
Строка "1"
преобразуется в число (1
) перед сравнением с true
и поэтому считается также равной true
.
Теперь, "ПОЧЕМУ?!?!" вопрос объясняется тем, что Javascript имеет свои корни в C-семействе языков. В котором любое число, отличное от 0, считается допустимым буфером true
.: -/
Ответ 3
Потому что 1 и "1" оба преобразуются в true, как числа. Это не относится к "а". Поэтому:
("1" == "1" == "1")
оценивается как
(("1" == "1") == "1")
который оценивается как
(true == "1")
Аналогично,
("1" == 1 == "1")
также верно или любая их комбинация. Фактически, любое ненулевое число при преобразовании в логическое значение истинно.
В то время как "a" не оценивает true.
Ответ 4
Это потому, что JavaScript является слабо типизированным языком. Это означает, что он недостаточно выразителен, чтобы говорить о типах и на самом деле неявно принуждает ценности относиться к типам, к которым у них нет семантического отношения. Итак, (1 == 1) == 1 оценивает значение true, потому что (1 == 1) правильно оценивает значение true, поэтому JavaScript оценивает (true) = 1. В частности, он превращает 1 в логическое (или true число - я забываю, что, но результат фактически тот же).
Дело в том, что JavaScript превращает один тип значения в другой тип значения за вашей спиной.
Ваш вопрос показывает, почему это проблема: ('a' == 'a') == 'a' - false, потому что ('a' == 'a') истинно, и JavaScript заканчивает сравнение ( true) == 'a'. Поскольку существует только нет разумный способ превратить булев в букву (или букву в логическое), это утверждение ложно. Конечно, это нарушает ссылочную прозрачность для (==).
Ответ 5
Это правда, что (1 == 1) == 1
. Тогда это будет true == 1
, но не в a == a == a
.
Ответ 6
Булевы обрабатываются как биты, каждый бит обозначает true или false (1 для true, 0 для false)
так что 1 означает true, а 0 означает false
и 1 == 1 == 1 будут похожи (1 == 1) == 1, true == 1, true
while 'a' == 'a' == 'a' будет ('a' == 'a') == 'a', true == 'a', false
BONUS: 0 == 1 == 0, 1 == 0 == 0 и 0 == 0 == 1 возвращает true