⚖️Gleichheit: == vs ===

=== vergleicht ohne Umwandlung: verschiedene Typen sind nie gleich. == wandelt die Operanden vorher nach festen Regeln um (Coercion). Klicke eine Zelle an, um die Regeln Schritt für Schritt zu sehen.

🧮Vergleichsmatrix

67 von 324 Paaren sind lose gleich, 13 strikt gleich. Jeder Wert wird pro Vergleich neu erzeugt ([] == [] ist also false).
true
false
1
0
-1
NaN
0n
"1"
"0"
""
" "
"abc"
null
undefined
[]
[0]
[1]
{}
true
false
1
0
-1
NaN
0n
"1"
"0"
""
" "
"abc"
null
undefined
[]
[0]
[1]
{}
truefalse
false == []true
false === [] → false
  1. 1Boolean-Operand → wird zuerst in eine Zahl umgewandelt
  2. 2ToNumber(false) = 0
  3. 3Primitiv == Objekt → Objekt wird mit ToPrimitive in einen primitiven Wert umgewandelt
  4. 4ToPrimitive([]): valueOf() liefert das Objekt selbst → toString() ergibt ""
  5. 5Zahl == String → String wird in eine Zahl umgewandelt
  6. 6ToNumber("") = 0 (leerer bzw. nur Leerzeichen-String ergibt 0)
  7. 7Gleicher Typ (number) → Vergleich wie === → true

Umsetzung von IsLooselyEqual nach ECMAScript 2026, §7.2.15 – jede Zelle ist in den Tests gegen den echten Operator geprüft.

📜Die Regeln von == in Kurzform

x == y
 ├─ gleicher Typ?                → wie ===
 ├─ null / undefined?            → true nur für null == undefined
 ├─ Zahl  vs. String             → String → Zahl
 ├─ BigInt vs. String            → String → BigInt
 ├─ Boolean beteiligt?           → Boolean → Zahl (true→1, false→0)
 ├─ Objekt vs. Primitiv          → ToPrimitive(Objekt): valueOf, dann toString
 ├─ BigInt vs. Zahl              → mathematischer Vergleich
 └─ sonst                        → false
✅ Empfehlung
Verwende immer === und !==. Einzige verbreitete Ausnahme: wert == null prüft auf null und undefined gleichzeitig.
💡 Object.is – die dritte Gleichheit
Object.is ist wie ===, behandelt aber NaN als gleich zu sich selbst und unterscheidet +0 und -0.

🧪Selbst nachprüfen

Berühmte Fälle

1console.log([] == false, [] == ![]);
2console.log("" == 0, "0" == false, " \n" == 0);
3console.log(null == 0, null == undefined);
4console.log(NaN == NaN, [1, 2] == "1,2");
Konsole (echt ausgeführt)
wird ausgeführt …

[] == ![] ist true: ![] ist false (Objekte sind truthy), und [] == false ergibt über ToPrimitive → "" → 0 == 0.

=== und Object.is

1console.log(0 === -0, Object.is(0, -0));
2console.log(NaN === NaN, Object.is(NaN, NaN));
3console.log([NaN].includes(NaN), [NaN].indexOf(NaN));
Konsole (echt ausgeführt)
wird ausgeführt …

includes nutzt SameValueZero (NaN gleich NaN), indexOf nutzt === und findet NaN deshalb nie.