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 == 0
sera true
pourquoi nous avons ===
.
En quoi est-ce Object.is
différent de ===
?
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 == 0
sera true
pourquoi nous avons ===
.
En quoi est-ce Object.is
différent de ===
?
Réponses:
===
est appelé opérateur de comparaison strict en JavaScript. Object.is
et l'opérateur de comparaison stricte se comporte exactement de la même manière sauf pour NaN
et +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 traiteNumber.NaN
comme 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
Vous pouvez trouver plus d'exemples ici .
Remarque : Object.is
fait 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.
.x
sur une chaîne la boxe dans un String
objet (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.
document.createElement('div').isEqualNode(document.createElement('div')) === true
Object.is
utilise 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 === NaN
est faux, mais Object.is(NaN, NaN)
est vrai+0 === -0
est vrai, mais Object.is(+0, -0)
est faux-0 === +0
est vrai, mais Object.is(-0, +0)
est fauxJavaScript a au moins quatre types "d'égalité":
==
), où les opérandes seront forcés d'essayer de les faire correspondre. Les règles sont clairement spécifiées , mais non évidentes. ( "" == 0
est true
; "true" == true
est false
, ...).===
), 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 NaN
et zéro positif et négatif.Object.is
).SameValue
sauf +0
et -0
sont identiques au lieu de différents (utilisés par Map
pour 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» ).
- 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 :
- Si Type (x) est différent de Type (y), renvoie false.
- 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.
- Renvoie SameValueNonNumber (x, y).
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.is
fonctionne, pour tous ceux qui sont intéressés à savoir. Une référence à You-Don't-Know-JS
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.
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
En un mot, ils sont similaires, mais ils sont Object.is
plus 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ù NaN
cela fonctionne plus comme correct, considérez tout de NaN
même.