В первых двух примерах, поскольку сравнение включает в себя примитивное значение b
, a
и c
в конечном итоге принуждаются к примитивам. В последнем случае, с другой стороны, вы сравниваете два разных объекта, и поэтому никакого принуждения не происходит.
Чтобы быть точным, дважды равным сравнение с булевым использует это правило из спецификации (принимая случай b == c
):
Если Type(x)
является Boolean
, возвращает результат сравнения ToNumber(x) == y
.
Значит, это означает, что ToNumber(b)
сравнивается с c
. ToNumber(b)
- 1. Таким образом, мы сравниваем 1
с c
. Далее, следующее правило:
Если Type(x)
либо String
или Number
и Type(y)
является Object
, возвращает результат сравнения x == ToPrimitive(y)
.
Таким образом, это означает, что мы сравниваем 1
с ToPrimitive(c)
которая ToPrimitive(Boolean(true))
. ToPrimitive
вызывает valueOf
, что дает 1
. Поэтому мы сравниваем 1
с 1
. QED.
В случае Вашего третьего примера, следующая часть спецификации применяется:
Если Type(x)
такая же, как Type(y)
, то ... Возвращает истину, если x
и y
относятся к одному объекту. В противном случае верните false.
Чтобы ответить на ваш вопрос:
Математически, как мы можем объяснить это противоречие?
Это не вопрос математики. Это вопрос определения сравнений в спецификации JS.
Два разных объекта никогда не будут сравниваться как равные. – Pointy
a == c Вы сравниваете ссылки на два объекта вместо ссылки на объект с примитивными данными –
Возможный дубликат [http://stackoverflow.com/questions/35104913/behaviour-of-javascript-objects](http://stackoverflow .com/questions/11704971/why-are-two-same-objects-not-equal-to-each-other) –