Object.is vs ===

141

Je suis tombé sur un exemple de code qui utilisait cette comparaison:

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

Je sais que ce false == 0sera truepourquoi nous avons ===.

En quoi est-ce Object.isdifférent de ===?

JS-JMS-WEB
la source

Réponses:

174

===est appelé opérateur de comparaison strict en JavaScript. Object.iset l'opérateur de comparaison stricte se comporte exactement de la même manière sauf pour NaNet +0/-0.

De MDN:

Object.is()n'est pas la même chose qu'être égal selon l' ===opérateur. L' ===opérateur (et l' ==opérateur également) traite les valeurs numériques -0 et +0 comme égales et traite Number.NaNcomme non égales à NaN.

Le code ci-dessous met en évidence la différence entre ===et 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

entrez la description de l'image ici

Vous pouvez trouver plus d'exemples ici .

Remarque : Object.isfait partie de la proposition ECMAScript 6 et n'est pas encore largement pris en charge (par exemple, il n'est pris en charge par aucune version d'Internet Explorer ou de nombreuses versions plus anciennes d'autres navigateurs). Cependant, vous pouvez utiliser un polyfill pour les navigateurs non ES6 qui peut être trouvé dans le lien ci-dessus.

Gurpreet Singh
la source
26
La première ligne de la réponse devrait être "Ils se comportent exactement de la même manière sauf pour NaN et +0 et -0", probablement.
Benjamin Gruenbaum
1
@BenjaminGruenbaum Bonne suggestion. Rend la réponse plus facile à lire. À votre santé.
Gurpreet Singh
3
@ humble.rumble cela a été longuement discuté - les méthodes statiques sont plus simples - elles n'ont pas de problèmes de contexte ou de problèmes primitifs. Par exemple, dans votre exemple, je m'attendrais à faux, mais les débutants en JS s'attendraient à vrai puisque faire .xsur une chaîne la boxe dans un Stringobjet (et non une valeur primitive de chaîne) et la comparaison serait entre un objet et une chaîne - c'est très subtile et constitue un piège - la statique évite ces problèmes, les méthodes statiques sont plus simples et plus faciles à utiliser.
Benjamin Gruenbaum
2
@ humble.rumble Pour comparer les nœuds DOM, il existe déjà une telle méthode, voir isEqualNode . Exemple:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W
2
Mise à jour 2017: Object.is () est désormais largement pris en charge dans tous les principaux navigateurs.
Sterling Bourne
56

Object.isutilise l' algorithme SameValue de la spécification , alors qu'il ===utilise l' algorithme d'égalité stricte . Une note sur l'algorithme d'égalité stricte souligne la différence:

Cet algorithme diffère de l'algorithme SameValue ... dans son traitement des zéros signés et des NaN.

Notez que:

  • NaN === NaNest faux, mais Object.is(NaN, NaN)est vrai
  • +0 === -0est vrai, mais Object.is(+0, -0)est faux
  • -0 === +0est vrai, mais Object.is(-0, +0)est faux

JavaScript a au moins quatre types "d'égalité":

  • "Loose" ( ==), où les opérandes seront forcés d'essayer de les faire correspondre. Les règles sont clairement spécifiées , mais non évidentes. ( "" == 0est true; "true" == trueest false, ...).
  • "Strict" ( ===), où les opérandes de types différents ne seront pas forcés (et ne seront pas égaux), mais voir la note ci-dessus sur NaNet zéro positif et négatif.
  • SameValue - comme indiqué ci-dessus (utilisé par Object.is).
  • SameValueZero - comme SameValuesauf +0et -0sont identiques au lieu de différents (utilisés par Mappour les touches et par Array.prototype.includes).

Il y a aussi l' équivalence d'objet , qui n'est pas fournie par le langage ou le runtime lui-même, mais est généralement exprimée comme suit: Les objets ont le même prototype, les mêmes propriétés et leurs valeurs de propriété sont les mêmes (selon une définition raisonnable de «le même» ).


Algorithme SameValue :

  • Si Type (x) est différent de Type (y), renvoie false.
  • Si Type (x) est Nombre, alors
    • Si x est NaN et y est NaN, renvoie true.
    • Si x est +0 et y est -0, renvoie false.
    • Si x est -0 et y est +0, renvoie false.
    • Si x est la même valeur numérique que y, renvoie true.
    • Renvoie false.
  • Renvoie SameValueNonNumber (x, y).

... où SameValueNonNumber est:

  • Assert: le type (x) n'est pas un nombre.
  • Assert: Type (x) est le même que Type (y).
  • Si Type (x) est indéfini, renvoie true.
  • Si Type (x) est Null, renvoie true.
  • Si Type (x) est String, alors
    • Si x et y sont exactement la même séquence d'unités de code (même longueur et mêmes unités de code aux indices correspondants), renvoie true; sinon, retournez false.
  • Si Type (x) est booléen, alors
    • Si x et y sont tous les deux vrais ou tous les deux faux, renvoie vrai; sinon, retournez false.
  • Si Type (x) est Symbol, alors
    • Si x et y sont tous les deux la même valeur de symbole, renvoie true; sinon, retournez false.
  • Renvoie true si x et y ont la même valeur d'objet. Sinon, retournez false.

Algorithme d'égalité stricte :

  1. Si Type (x) est différent de Type (y), renvoie false.
  2. Si Type (x) est Nombre, alors
    • Si x est NaN, renvoie false.
    • Si y est NaN, renvoie false.
    • Si x est la même valeur numérique que y, renvoie true.
    • Si x est +0 et y est -0, renvoie vrai.
    • Si x est -0 et y est +0, renvoie vrai.
    • Renvoie false.
  3. Renvoie SameValueNonNumber (x, y).
TJ Crowder
la source
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;
}

Ce qui précède est la fonction polyfill pour montrer comment Object.isfonctionne, pour tous ceux qui sont intéressés à savoir. Une référence à You-Don't-Know-JS

Isaac
la source
2

Résumé:

La Object.is()fonction prend 2 valeurs comme arguments et renvoie true si les 2 valeurs données sont exactement les mêmes, sinon elle retournera false.

Pourquoi avons nous besoin de ça?

Vous pourriez penser que nous avons déjà une égalité stricte (vérifie le type + la valeur) en vérifiant javascript avec l' ===opérateur, pourquoi avons-nous besoin de cette fonction? Une égalité stricte n'est pas suffisante dans certains cas et ce sont les suivants:

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

Object.is() nous aide en étant capable de comparer ces valeurs pour voir si elles sont similaires, ce que l'opérateur d'égalité stricte ne peut pas faire.

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

Willem van der Veen
la source
0

En un mot, ils sont similaires, mais ils sont Object.isplus intelligents et plus précis ...

Regardons ceci ...

+0 === -0 //true

Mais ce n'est pas tout à fait juste car il ignore -et +avant ...

Maintenant, nous utilisons:

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

Comme vous le voyez, c'est plus précis à comparer.

Dans le cas où NaNcela fonctionne plus comme correct, considérez tout de NaNmême.

Alireza
la source