Abschnitt 3 · Lektion 2
Vergleichen
Ein Vergleich stellt eine Frage und liefert true oder false. Damit ist er die Zutat, aus der die nächsten Lektionen Entscheidungen bauen.
Die Frage, die dabei jeder Anfänger stellt: Warum gibt es zwei Gleichheitszeichen und drei?
Die kurze Antwort
Nimm immer drei. Wenn du nur das mitnimmst, hast du das Wichtigste.
Die lange Antwort
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Drei Zeichen: gleicher Wert UND gleicher Typ.
console.log("Streng, Text gegen Zahl:", "5" === 5);
console.log("Streng, Zahl gegen Zahl:", 5 === 5);
// Zwei Zeichen: erst umwandeln, dann vergleichen.
console.log("Lose, Text gegen Zahl:", "5" == 5);
// Und das Gegenteil davon.
console.log("Streng ungleich:", "5" !== 5);
console.log("Lose ungleich:", "5" != 5); === vergleicht Wert und Typ. Sind die Typen verschieden, ist die Antwort false, ohne dass irgendetwas weiter passiert. "5" === 5 ist also false: das eine ist Text, das andere eine Zahl.
== wandelt vorher um. Es sieht, dass links Text und rechts eine Zahl steht, macht aus dem Text eine Zahl und vergleicht dann. "5" == 5 ist deshalb true.
Dasselbe gilt für die Verneinung: !== fragt streng, != lose.
Auf den ersten Blick klingt == sogar hilfreich. Es macht doch genau das, was man meint. Das Problem ist die Frage, was es sonst noch alles tut.
Warum niemand die Regeln von == kennt
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Kein Mensch hat diese Regeln im Kopf. Rate erst, dann schau nach.
console.log("0 == false: ", 0 == false);
console.log("\"\" == false: ", "" == false);
console.log("\"0\" == false: ", "0" == false);
console.log("null == false: ", null == false);
console.log("null == undefined:", null == undefined);
// Und mit drei Zeichen ist alles davon schlicht false.
console.log("Streng, alle:", 0 === false, "" === false, "0" === false); Rate bei jeder Zeile, bevor du in die Console schaust.
0 == false ist wahr. "" == false ist wahr. "0" == false ist auch wahr, obwohl "0" ein Text mit einem Zeichen darin ist. null == false dagegen ist falsch, und da hört die Logik endgültig auf.
Diese Regeln stehen in der Sprachspezifikation und füllen dort mehrere Seiten. Niemand hat sie im Kopf, auch Leute nicht, die das seit zwanzig Jahren machen. Sie schlagen nach, wenn sie sie brauchen, und meistens brauchen sie sie nicht, weil sie === benutzen.
Nachschlagen kannst du hier übrigens auch, und zwar schneller als in der Spezifikation: Die Eingabezeile der Console beantwortet jeden dieser Vergleiche sofort. Denk dir eigene Paare aus, rate das Ergebnis und tipp es ein. [] == false ist wahr. [] == "" ist auch wahr. Nach fünf solchen Zeilen hast du ein besseres Gefühl dafür, warum niemand diese Regeln lernt, als jeder Absatz es geben könnte.
Deshalb ist der Merksatz nicht „=== ist strenger”, sondern „=== ist vorhersagbar”. Du siehst zwei Werte, du kennst ihre Typen, du weißt das Ergebnis. Mehr will man von einem Vergleich nicht.
Wenn du wirklich Text mit Zahl vergleichen willst, wandelst du vorher um, mit Number() aus Lektion 2.7. Dann steht die Umwandlung im Code und ist eine Entscheidung statt eines Zufalls.
Die eine sinnvolle Ausnahme
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> let nieGefuellt;
const absichtlichLeer = null;
const echterWert = 0;
// Mit zwei Zeichen trifft ein einziger Vergleich beide Sorten von "nichts".
console.log("Nie gefüllt: ", nieGefuellt == null);
console.log("Absichtlich leer: ", absichtlichLeer == null);
// Und die Null wird dabei nicht mitgefangen, das ist der Punkt.
console.log("Echte Null: ", echterWert == null); Es gibt genau eine Stelle, an der die lose Form die bessere ist, und die solltest du kennen, weil du sie in fremdem Code sehen wirst.
wert == null ist wahr für null und für undefined. Ein einziger Vergleich fängt also beide Sorten von „nichts” aus Lektion 2.6 ab. Streng geschrieben bräuchtest du zwei Vergleiche.
Wichtig dabei: Die Null wird nicht mitgefangen, und der leere Text auch nicht. Das ist genau die Eingrenzung, die man an dieser Stelle will.
Dass ausgerechnet die verrufene Schreibweise hier die richtige ist, hat einen Grund: Es ist der einzige Fall, in dem alle Beteiligten die Regel tatsächlich kennen.
Größer, kleiner und Texte
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> console.log("Größer: ", 10 > 3);
console.log("Kleiner gleich:", 10 <= 10);
// Texte werden Zeichen für Zeichen verglichen, nicht nach Länge.
console.log("\"Apfel\" < \"Birne\":", "Apfel" < "Birne");
console.log("\"Zebra\" < \"apfel\":", "Zebra" < "apfel");
// Groß vor klein: alle Großbuchstaben kommen vor allen kleinen.
console.log("\"a\" < \"B\":", "a" < "B"); <, >, <= und >= verhalten sich, wie du es erwartest. Sie haben keine strenge Variante, es gibt kein <==.
Interessanter ist, was passiert, wenn du damit Texte vergleichst. Sie werden Zeichen für Zeichen verglichen, nicht nach Länge. Beim ersten Unterschied steht das Ergebnis fest.
Und dabei kommt eine Überraschung: Alle Großbuchstaben kommen vor allen kleinen. "Zebra" < "apfel" ist wahr. Der Grund ist, dass Buchstaben intern Nummern sind und die Großbuchstaben in dieser Nummerierung vorn liegen. Für eine Sortierung nach Alphabet taugt der einfache Vergleich damit nicht, und Umlaute machen es nicht besser. Was man stattdessen nimmt, kommt in Lektion 6.8.
Der Vergleich mit < und > ist übrigens die einzige Stelle, an der auch die strenge Denkweise nicht davor schützt, dass umgewandelt wird: "10" > 3 ist true, weil hier gerechnet werden muss. Wandle Eingaben also weiterhin selbst um, bevor du sie vergleichst.
Zum Mitnehmen
=== ist nicht strenger als ==, sondern vorhersagbar. Das ist der ganze Grund, warum man es nimmt.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.