Object.is vs ===

141

Ich bin auf ein Codebeispiel gestoßen, das diesen Vergleich verwendete:

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

Ich weiß , false == 0wird sein , truedass der Grund , warum wir haben=== .

Wie Object.isunterscheidet sich von ===?

JS-JMS-WEB
quelle

Antworten:

174

===wird in JavaScript als strikter Vergleichsoperator bezeichnet. Object.isund strikte Vergleichsoperatoren verhalten sich bis auf NaNund genau gleich+0/-0 .

Von MDN:

Object.is()Methode ist nicht dasselbe wie laut ===Operator gleich zu sein . Der ===Operator (und auch der ==Operator) behandelt die Zahlenwerte -0 und +0 als gleich und Number.NaNals ungleich NaN.

Der folgende Code hebt den Unterschied zwischen ===und hervor 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

Geben Sie hier die Bildbeschreibung ein

Weitere Beispiele finden Sie hier .

Hinweis : Object.isist Teil des ECMAScript 6-Vorschlags und wird noch nicht allgemein unterstützt (z. B. wird es von keiner Version von Internet Explorer oder vielen älteren Versionen anderer Browser unterstützt). Sie können jedoch eine Polyfüllung für Nicht-ES6-Browser verwenden, die Sie unter dem oben angegebenen Link finden.

Gurpreet Singh
quelle
26
Die erste Zeile der Antwort sollte wahrscheinlich "Sie verhalten sich bis auf NaN und +0 und -0 genau gleich" lauten.
Benjamin Gruenbaum
1
@BenjaminGruenbaum Guter Vorschlag. Erleichtert das Lesen der Antwort. Prost.
Gurpreet Singh
3
@ bescheiden.rumble dies wurde ausführlich diskutiert - statische Methoden sind einfacher - sie haben keine Kontextprobleme oder primitiven Probleme. Zum Beispiel würde ich in Ihrem Beispiel false erwarten, aber Neulinge in JS würden true erwarten , da sie es .xfür eine Zeichenfolge in ein StringObjekt (und nicht für einen primitiven Zeichenfolgenwert) einfügen und der Vergleich zwischen einem Objekt und einer Zeichenfolge erfolgen würde - das ist sehr subtil und eine Falle - Statik vermeidet diese Probleme, statische Methoden sind einfacher und benutzerfreundlicher.
Benjamin Gruenbaum
2
@ bescheiden.rumble Zum Vergleichen von DOM-Knoten gibt es bereits eine solche Methode, siehe isEqualNode . Beispiel:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W
2
Update 2017: Object.is () wird jetzt in allen gängigen Browsern weitgehend unterstützt.
Sterling Bourne
56

Object.isverwendet den SameValue-Algorithmus der Spezifikation , während ===der Strict Equality-Algorithmus verwendet wird . Ein Hinweis zum Strict Equality Algorithm macht den Unterschied deutlich:

Dieser Algorithmus unterscheidet sich vom SameValue-Algorithmus ... in der Behandlung von vorzeichenbehafteten Nullen und NaNs.

Beachten Sie, dass:

  • NaN === NaNist falsch, aber Object.is(NaN, NaN)wahr
  • +0 === -0ist wahr, aber Object.is(+0, -0)falsch
  • -0 === +0ist wahr, aber Object.is(-0, +0)falsch

JavaScript hat mindestens vier Arten von "Gleichheit":

  • "Loose" ( ==), wo die Operanden gezwungen werden, zu versuchen, sie zusammenzubringen. Die Regeln sind klar festgelegt , aber nicht offensichtlich. ( "" == 0ist true; "true" == trueistfalse , ...).
  • "Strict" ( ===), wobei Operanden unterschiedlicher Typen nicht erzwungen werden (und nicht gleich sind), siehe jedoch den obigen Hinweis zuNaN und positive und negative Null.
  • SameValue - wie oben aufgeführt (verwendet von Object.is ).
  • SameValueZero - wie SameValueaußer +0und -0sind gleich statt verschieden (wird von Mapfür Schlüssel und von verwendet Array.prototype.includes).

Es gibt auch Objektäquivalenz , die nicht von der Sprache oder der Laufzeit selbst bereitgestellt wird, sondern normalerweise ausgedrückt wird als: Die Objekte haben denselben Prototyp, dieselben Eigenschaften und ihre Eigenschaftswerte sind dieselben (nach einer vernünftigen Definition von "gleich"). ).


SameValue-Algorithmus :

  • Wenn sich Typ (x) von Typ (y) unterscheidet, geben Sie false zurück.
  • Wenn Typ (x) Nummer ist, dann
    • Wenn x NaN und y NaN ist, geben Sie true zurück.
    • Wenn x +0 und y -0 ist, geben Sie false zurück.
    • Wenn x -0 und y +0 ist, geben Sie false zurück.
    • Wenn x der gleiche Zahlenwert wie y ist, geben Sie true zurück.
    • Falsch zurückgeben.
  • Geben Sie SameValueNonNumber (x, y) zurück.

... wo SameValueNonNumber ist:

  • Behauptung: Typ (x) ist keine Zahl.
  • Behauptung: Typ (x) ist der gleiche wie Typ (y).
  • Wenn Typ (x) undefiniert ist, geben Sie true zurück.
  • Wenn Typ (x) Null ist, geben Sie true zurück.
  • Wenn Typ (x) String ist, dann
    • Wenn x und y genau die gleiche Folge von Codeeinheiten sind (gleiche Länge und gleiche Codeeinheiten an entsprechenden Indizes), geben Sie true zurück. Andernfalls geben Sie false zurück.
  • Wenn Typ (x) Boolesch ist, dann
    • Wenn x und y beide wahr oder beide falsch sind, geben Sie true zurück. Andernfalls geben Sie false zurück.
  • Wenn Typ (x) Symbol ist, dann
    • Wenn x und y beide der gleiche Symbolwert sind, geben Sie true zurück. Andernfalls geben Sie false zurück.
  • Geben Sie true zurück, wenn x und y der gleiche Objektwert sind. Andernfalls geben Sie false zurück.

Strenger Gleichstellungsalgorithmus :

  1. Wenn sich Typ (x) von Typ (y) unterscheidet, geben Sie false zurück.
  2. Wenn Typ (x) Nummer ist, dann
    • Wenn x NaN ist, geben Sie false zurück.
    • Wenn y NaN ist, geben Sie false zurück.
    • Wenn x der gleiche Zahlenwert wie y ist, geben Sie true zurück.
    • Wenn x +0 und y -0 ist, geben Sie true zurück.
    • Wenn x -0 und y +0 ist, geben Sie true zurück.
    • Falsch zurückgeben.
  3. Geben Sie SameValueNonNumber (x, y) zurück.
TJ Crowder
quelle
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;
}

Das Obige ist die Polyfill-Funktion, die zeigt, wie es Object.isfunktioniert, für alle Interessierten. Ein Verweis auf You-Don't-Know-JS

Isaac
quelle
2

Zusammenfassung:

Die Object.is()Funktion verwendet 2 Werte als Argumente und gibt true zurück, wenn die 2 angegebenen Werte exakt gleich sind. Andernfalls wird false zurückgegeben.

Warum brauchen wir das?

Sie könnten denken, wir haben bereits eine strikte Gleichheitsprüfung (prüft Typ + Wert) in Javascript mit dem ===Operator. Warum brauchen wir diese Funktion? Nun, strenge Gleichheit ist in einigen Fällen nicht ausreichend und sie sind die folgenden:

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

Object.is() hilft uns, indem wir diese Werte vergleichen können, um festzustellen, ob sie ähnlich sind, was der strenge Gleichheitsoperator nicht kann.

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
quelle
0

Kurz gesagt, sie sind ähnlich, aber Object.isintelligenter und genauer ...

Schauen wir uns das an ...

+0 === -0 //true

Aber das ist nicht ganz richtig, da es ignoriert -und +vorher ...

Jetzt verwenden wir:

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

Wie Sie sehen, ist dies genauer zu vergleichen.

Auch in diesem Fall NaNfunktioniert das eher wie richtig, wie man es auch betrachtet NaN.

Alireza
quelle