Signatur
Beschreibung
Object.is() implementiert den Vergleichsalgorithmus SameValue aus der ECMAScript-Spezifikation. Zwei Werte gelten als gleich, wenn beide undefined, beide null, beide true bzw. beide false sind, wenn beide Strings mit denselben Zeichen in derselben Reihenfolge sind, wenn beide dasselbe Objekt referenzieren, wenn beide BigInts mit demselben Wert oder beide dasselbe Symbol sind. Bei Zahlen sind zwei Werte gleich, wenn beide +0, beide -0, beide NaN oder beide ungleich null, nicht NaN und vom Wert her gleich sind.
Anders als == wandelt Object.is() keine Typen um. "" == false ergibt also true, Object.is("", false) dagegen false. Von === unterscheidet sich die Methode nur in zwei Randfällen: Object.is(NaN, NaN) ergibt true (bei === ist das false), und Object.is(0, -0) ergibt false (bei === ist das true).
Nützlich ist die Methode vor allem dort, wo diese Randfälle wichtig sind: bei der Änderungserkennung in State-Management-Bibliotheken (React vergleicht zum Beispiel Hook-Abhängigkeiten und State mit Object.is), in Memoisierungs-Caches, in numerischen Algorithmen, in denen das Vorzeichen der Null zählt (z. B. 1 / -0 === -Infinity), und in Test-Frameworks (expect(x).toBe(y) in Jest).
Objekte werden nur nach Identität verglichen, nicht nach Inhalt. Zwei verschiedene Objekte mit gleichen Eigenschaften sind also nicht gleich. Für einen Vergleich nach Inhalt (Deep Equality) braucht man eine eigene Funktion oder eine Bibliothek.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value1 Pflicht | any | Der erste Wert des Vergleichs. Beliebiger Typ, einschließlich primitiver Werte, Objekte, Symbole und BigInts. | |
| $value2 Pflicht | any | Der zweite Wert des Vergleichs. Wird ohne Typumwandlung mit value1 verglichen. |
Rückgabewert
true, wenn beide Werte nach dem SameValue-Algorithmus derselbe Wert sind, sonst false.Beispiele
Grundlegende Vergleiche und Unterschiede zu ===
console.log(Object.is(25, 25)); // true
console.log(Object.is('foo', 'foo')); // true
console.log(Object.is('foo', 'bar')); // false
console.log(Object.is(null, undefined)); // false
console.log(Object.is('', false)); // false (keine Typumwandlung)
// Die beiden Randfälle, in denen es von === abweicht
console.log(NaN === NaN, Object.is(NaN, NaN)); // false true
console.log(0 === -0, Object.is(0, -0)); // true false
console.log(Object.is(-0, -0)); // true
console.log(Object.is(0n, -0n)); // true (bei BigInt gibt es kein -0)
Objekte werden nach Identität verglichen
const user = { name: 'Anna' };
const sameRef = user;
const copy = { ...user };
console.log(Object.is(user, sameRef)); // true – dieselbe Referenz
console.log(Object.is(user, copy)); // false – anderes Objekt, gleicher Inhalt
const sym = Symbol('id');
console.log(Object.is(sym, sym)); // true
console.log(Object.is(Symbol('id'), Symbol('id'))); // false
Änderungserkennung in einem einfachen Store
const createStore = (initial) => {
let state = initial;
const listeners = new Set();
return {
get: () => state,
set: (next) => {
// Nur bei echter Änderung benachrichtigen – NaN → NaN zählt nicht als Änderung
if (Object.is(state, next)) return;
state = next;
listeners.forEach((fn) => fn(state));
},
subscribe: (fn) => (listeners.add(fn), () => listeners.delete(fn)),
};
};
const store = createStore(NaN);
store.subscribe((v) => console.log('Neuer Wert:', v));
store.set(NaN); // keine Ausgabe
store.set(-0); // Neuer Wert: -0
store.set(0); // Neuer Wert: 0 (Vorzeichen hat sich geändert)
Negative Null erkennen
const isNegativeZero = (n) => Object.is(n, -0);
const temperatures = [0, -0, 3.5, -1 * 0];
console.log(temperatures.map(isNegativeZero));
// Math.round kann -0 liefern
console.log(isNegativeZero(Math.round(-0.4)));
// Wichtig · Fallstricke
- Kein Deep-Equal: Objekte, Arrays,
Date- undMap-Instanzen werden nur nach Referenz verglichen.Object.is([], [])ergibtfalse. - Andere Algorithmen in der Sprache:
Array.prototype.includes(),MapundSetverwenden SameValueZero:NaNgilt dort als gleich zu sich selbst,+0und-0aber ebenfalls als gleich.indexOf()verwendet dagegen===und findetNaNdeshalb nie. NurObject.is()unterscheidet+0und-0. - Nicht als Standard-Vergleich verwenden: Im normalen Code ist
===meist die richtige Wahl. MitObject.is()kann eine-0aus Berechnungen wieMath.round(-0.4)unerwartet zufalseführen. - Nur ein Argument: Fehlt das zweite Argument, wird es als
undefinedbehandelt.Object.is(undefined)ergibt alsotrue. - Kompatibilität: Seit ES2015 in allen modernen Browsern und in Node.js verfügbar (Baseline), nicht im Internet Explorer. Ein Polyfill ist einfach:
(x, y) => x === y ? x !== 0 || 1 / x === 1 / y : x !== x && y !== y.