Object.is vs ===

Я наткнулся на пример кода, который использовал это сравнение:

var someVar = 0;
Object.is(false, someVar); //Returns false 

Я знаю, что false == 0 будет true, поэтому мы имеем ===.

Как Object.is отличается от ===?

Ответ 1

=== называется оператором строгого сравнения в JavaScript. Object.is и оператор строгого сравнения ведут себя одинаково, за исключением NaN и +0/-0.

Из MDN:

Метод Object.is() - это не то же самое, что быть равным согласно оператору ===. Оператор === (и оператор ==) обрабатывает числовые значения -0 и +0 как равные и обрабатывает Number.NaN как не равные NaN.

Приведенный ниже код подчеркивает разницу между === и Object.is().

console.log(+0 === -0); //true
console.log(Object.is(+0, -0)); //false

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); //true

console.log(Number.NaN === Number.NaN); // false
console.log(Object.is(Number.NaN, Number.NaN)); // true

console.log(NaN === Number.NaN); // false
console.log(Object.is(NaN, Number.NaN)); // true

enter image description here

Вы можете найти больше примеров здесь.

Примечание: Object.is является частью предложения ECMAScript 6 и пока широко не поддерживается (например, не поддерживается ни одной версией Internet Explorer или многими более старыми версиями других браузеров). Однако вы можете использовать polyfill для браузеров не-ES6, которые можно найти по ссылке, приведенной выше.

Ответ 2

Object.is использует спецификационный алгоритм SameValue, тогда как === использует алгоритм строгого равенства. Примечание об алгоритме строгого равенства выявляет разницу:

Этот алгоритм отличается от алгоритма SameValue... обработкой подписанных нулей и NaN.

Обратите внимание, что:

  • NaN === NaN ложно, но Object.is(NaN, NaN) верно
  • +0 === -0 верно, но Object.is(+0, -0) неверно
  • -0 === +0 верно, но Object.is(-0, +0) неверно

В JavaScript есть как минимум четыре вида "равенства":

  • "Loose" (==), где операнды будут принудительно пытаться сопоставить их. Правила четко указаны, но неочевидны. ("" == 0 это true; "true" == true это false ,...).
  • "Строгое" (===), где операнды разных типов не будут принудительно (и не будут равны), но см. Примечание выше о NaN и положительном и отрицательном нуле.
  • SameValue - как указано выше (используется Object.is).
  • SameValueZero - как и SameValue за исключением того, что +0 и -0 являются одинаковыми, а не разными (используются Map для ключей и Array.prototype.includes).

Также существует эквивалентность объекта, которая не обеспечивается самим языком или средой выполнения, но обычно выражается следующим образом: объекты имеют один и тот же прототип, одинаковые свойства и значения их свойств одинаковы (по некоторым разумным определениям "то же самое")).


Алгоритм SameValue:

  • Если Type (x) отличается от Type (y), вернуть false.
  • Если тип (х) является число, то
    • Если x равен NaN, а y равен NaN, вернуть true.
    • Если x равен +0, а y равен -0, вернуть false.
    • Если x равен -0, а y равен +0, вернуть false.
    • Если x - это то же самое числовое значение, что и y, вернуть true.
    • Вернуть ложь.
  • Вернуть SameValueNonNumber (x, y).

... где SameValueNonNumber:

  • Утверждение: Тип (x) не является Number.
  • Утверждение: тип (x) совпадает с типом (y).
  • Если Тип (x) не определен, вернуть true.
  • Если Type (x) равен Null, вернуть true.
  • Если Тип (x) является Строкой, тогда
    • Если x и y - это одна и та же последовательность единиц кода (одинаковая длина и одинаковые единицы кода при соответствующих индексах), верните true; в противном случае верните false.
  • Если тип (x) является логическим, то
    • Если x и y оба имеют значение true или оба false, вернуть true; в противном случае верните false.
  • Если Тип (x) является Символом, тогда
    • Если x и y оба являются одним и тем же значением Symbol, верните true; в противном случае верните false.
  • Вернуть true, если x и y - это одно и то же значение объекта. В противном случае верните false.

Алгоритм строгого равенства:

  1. Если Type (x) отличается от Type (y), вернуть false.
  2. Если тип (х) является число, то
    • Если x равен NaN, вернуть false.
    • Если y равен NaN, вернуть false.
    • Если x - это то же самое числовое значение, что и y, вернуть true.
    • Если x равен +0, а y равен -0, верните true.
    • Если x равен -0, а y равен +0, верните true.
    • Вернуть ложь.
  3. Вернуть SameValueNonNumber (x, y).

Ответ 3

Object.is = function(v1, v2){
  //test for '-0'
  if(v1 === 0 && v2 === 0) {
    return 1 / v1 === 1 / v2;
  }
  
  //test for 'NaN'
  if(v1 !== v1) {
    return v2 !== v2;
  }
  
  //everything else
  return v1 === v2;
}

Ответ 4

Резюме:

Функция Object.is() принимает 2 значения в качестве аргументов и возвращает истину, если 2 заданных значения в точности совпадают, в противном случае она вернет ложь.

Почему нам это надо?

Вы можете подумать, у нас уже есть строгое равенство (проверяет тип + значение), проверяющее в javascript с помощью оператора ===, зачем нам эта функция? Ну, строгое равенство не достаточно в некоторых случаях, и они следующие:

console.log(NaN === NaN);   // false
console.log(-0 === +0);     // true