Object.is vs ===


144

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

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

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

Чем Object.isотличается от ===?

Ответы:


177

===называется оператором строгого сравнения в 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

введите описание изображения здесь

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

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


30
Первая строка ответа должна быть «Они ведут себя точно так же, за исключением NaN и +0 и -0», вероятно.
Бенджамин Грюнбаум,

1
@BenjaminGruenbaum Хорошее предложение. Облегчает чтение ответа. Ура.
Гурприт Сингх

3
@ humble.rumble это обсуждалось подробно - статические методы проще - у них нет проблем с контекстом или примитивов. Например, в вашем примере я ожидал бы false, но новички в JS ожидали бы true, поскольку выполнение .xв строке помещает его в Stringобъект (а не в строковое примитивное значение), и сравнение будет между объектом и строкой - это очень тонкий и ловушка - статика позволяет избежать этих проблем, статические методы проще и проще в использовании.
Бенджамин Грюнбаум

2
@ humble.rumble Для сравнения узлов DOM уже существует такой метод, см. isEqualNode . Пример:document.createElement('div').isEqualNode(document.createElement('div')) === true
Роб У

2
Обновление 2017 г .: Object.is () теперь широко поддерживается во всех основных браузерах.
Стерлинг Борн

58

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

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

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

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

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

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

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


Алгоритм SameValue :

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

... где SameValueNonNumber :

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

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

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

2

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;
}

Вышеупомянутая функция polyfill показывает, как Object.isработает, для всех, кому интересно знать. Ссылка на You-Don't-Know-JS


2

Резюме:

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

Зачем нам это нужно?

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

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

Object.is() помогает нам, имея возможность сравнивать эти значения, чтобы увидеть, похожи ли они, чего не может сделать оператор строгого равенства.

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


0

В двух словах они похожи, но Object.isумнее и точнее ...

Посмотрим на это ...

+0 === -0 //true

Но это не совсем верно, так как игнорировал -и +раньше ...

Теперь используем:

Object.is(+0, -0) //false

Как видите, это точнее сравнивать.

Также в случае, если NaNэто работает скорее правильно, так как считайте любое NaNто же самое.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.