Ответ 1
Ссылки на объекты по сравнению с ==
или !=
(или ===
или !==
) сравниваются в зависимости от того, ссылаются ли они на тот же объект. Если это так, они равны; если нет, они не равны.
Но операторы сравнения реляций (>
, <
, >=
и <=
) не сравнивают ссылки, они принуждают свои операнды к чему-то, что они могут сравнить: Числа или строки.
В случае new Object()
это принуждение заканчивается созданием строки: "[object Object]"
. И, конечно, "[object Object]" >= "[object Object]"
истинно, потому что они равны.
Таким образом, вы фактически делаете следующее:
console.log(a == b); //false
console.log(String(a) > String(b)); //false
console.log(String(b) > String(a)); //false
console.log(String(a) >= String(b)); //true
console.log(String(b) >= String(a)); //true
... но обратите внимание, что другие типы объектов взаимно запрещают, поскольку объекты могут выбирать, как они принуждают в этой ситуации (где спецификация предпочитает число над строкой) путем реализации/переопределения valueOf
. Например, Date
объекты принуждают к числу, когда вы применяете к ним реляционный оператор, если другой операнд также может принуждать к порядку. Таким образом, вы можете надежно использовать dt1 > dt2
, чтобы увидеть, если dt1
представляет дату/время после dt2
— но вы не можете использовать dt1 == dt2
, чтобы проверить, имеют ли теги dt1
и dt2
(два отдельных объекта Date
) те же дату/время, потому что ==
будет проверять посмотрите, являются ли они тем же самым объектом. Это приводит нас к этому удовольствию:
var dt1 = new Date(2016, 5, 23);
var dt2 = new Date(2016, 5, 23);
console.log(dt1 < dt2); // false
console.log(dt1 > dt2); // false
console.log(dt1 == dt2); // false!