Подтвердить что ты не робот

Сравнение нового Object() с другим новым Object() в JavaScript

Я создал два новых объекта:

var a = new Object();
var b = new Object();

и после сравнения у меня есть следующие результаты:

var a = new Object();
var b = new Object();
console.log(a == b); //false
console.log(a > b); //false
console.log(b > a); //false
console.log(a >= b); //true
console.log(b >= a); //true
4b9b3361

Ответ 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!

Ответ 2

Поведение полностью определено в стандартах ECMAScript.

  • a == b - это false, потому что они не относятся к одному и тому же объекту, как определено в разделе Абстрактное равенство:

    1. Если тип (x) совпадает с типом (y), то

      а. Верните результат выполнения строгого сравнения равенств x === y.

Параметр Сравнение строгого равенства определяет, после проверки всех других типов:

  1. Если x и y - одно и то же значение Object, верните true.
  2. Возвращает false.

a < b false, потому что алгоритм абстрактного реляционного сравнения сначала преобразует операнды в типы без объектов через абстрактную операцию ToPrimitive (которая в случае объектов приводит к строковому представлению "[object Object]").

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

a <= b true, потому что b < a false, согласно старому определению оператора меньше или равно (< =).

  1. Пусть r является результатом выполнения абстрактного реляционного сравнения rval < lval с LeftFirst равным false. (см. 11.8.5).
  2. Если r истинно или undefined, верните false. В противном случае верните true.

Опять же, операция абстрактного реляционного сравнения преобразует операнды в представления строк "[object Object]", которые будут равны друг другу, так что сравнение b < a будет оцениваться как false: