mitmario.dev

Logische Operatoren

JavaScript Im Browser 4 Min Lesezeit 4 BeispieleLektion 4 von 9

Ein einzelner Vergleich reicht selten. Meistens hängt eine Entscheidung an mehreren Bedingungen gleichzeitig, und dafür gibt es drei Zeichen.

Und, oder, nicht

Und, oder, nicht
const alter = 20;
const hatTicket = true;

// && verlangt beides.
console.log("Beides:", alter >= 18 && hatTicket);
console.log("Nur eins:", alter >= 18 && false);

// || verlangt nur eines.
console.log("Eines reicht:", alter >= 18 || false);
console.log("Keines:      ", alter < 18 || false);

// ! dreht um.
console.log("Umgedreht:", !hatTicket);
console.log("Nicht volljährig:", !(alter >= 18));

&& heißt und: Beide Seiten müssen wahr sein.

|| heißt oder: Eine der beiden reicht. Die beiden senkrechten Striche tippst du auf der deutschen Tastatur mit AltGr und der Taste links neben dem Y.

! heißt nicht und dreht um. Es steht vor dem Wert, nicht dahinter.

Beim Verneinen eines ganzen Ausdrucks brauchst du Klammern: !(alter >= 18) verneint den Vergleich, !alter >= 18 würde erst alter verneinen und das Ergebnis dann mit 18 vergleichen. Das ist ein Fehler, den niemand sieht, weil er kein Fehler ist, sondern einfach etwas anderes.

Und noch ein Hinweis für später: && bindet stärker als ||, genau wie mal stärker bindet als plus. a || b && c ist also a || (b && c). Setz die Klammer hin, sobald beide in einer Zeile stehen.

Sie liefern keinen Wahrheitswert

Jetzt der Teil, den man in fremdem Code ständig sieht und beim Lernen fast nie erklärt bekommt.

Sie liefern keinen Wahrheitswert
// || gibt den ersten Wert zurück, der wahr ist.
console.log("Leerer Name:", "" || "Gast");
console.log("Echter Name:", "Mario" || "Gast");

// && gibt den ersten zurück, der falsch ist, sonst den letzten.
console.log("Erster falsch:", "" && "Mario");
console.log("Beide wahr:   ", "Mario" && "Leipzig");

// Deshalb steht da nicht immer true oder false.
console.log("Typ:", typeof ("" || "Gast"));

&& und || geben nicht true oder false zurück. Sie geben einen der beiden Werte zurück, die du ihnen gegeben hast.

|| liefert den ersten Wert, der wahr ist. Ist keiner wahr, den letzten. && liefert den ersten Wert, der falsch ist. Ist keiner falsch, den letzten.

Beides zusammen mit der Wahrheitsregel aus Lektion 3.3 ergibt eine der meistbenutzten Redewendungen der Sprache:

const anzeigename = name || "Gast";

Steht in name etwas, kommt das heraus. Ist er leer, kommt "Gast" heraus. Ein Standardwert in einer Zeile, ohne if.

Dass in einer Bedingung trotzdem alles funktioniert, liegt daran, dass if selbst umwandelt. Der Rückgabewert ist nur dann sichtbar, wenn du ihn irgendwo ablegst oder ausgibst.

Oder wenn du ihn in der Eingabezeile der Console erfragst, denn die antwortet immer mit dem Wert des Ausdrucks. Tipp "" || "Gast", und zurück kommt "Gast" in Anführungszeichen: ein Text, kein true. Tipp 0 || 5, und zurück kommt 5. Der Satz oben ist damit keine Behauptung über etwas Unsichtbares mehr.

Warum die Null zur Falle wird

Warum die Null zur Falle wird
const nochNichtGespielt = null;
const nullPunkteErreicht = 0;

// Mit || sieht beides gleich aus, und das ist falsch.
console.log("Nichts gespielt, mit ||:", nochNichtGespielt || "keine Angabe");
console.log("Null Punkte,     mit ||:", nullPunkteErreicht || "keine Angabe");

// Mit ?? bleibt die echte Null stehen.
console.log("Nichts gespielt, mit ??:", nochNichtGespielt ?? "keine Angabe");
console.log("Null Punkte,     mit ??:", nullPunkteErreicht ?? "keine Angabe");

// Auch der leere Text überlebt das ??.
console.log("Leerer Text, mit ||:", "" || "Ersatz");
console.log("Leerer Text, mit ??:", "" ?? "Ersatz");

Und hier bricht die Redewendung zusammen.

|| prüft auf wahr genug, und 0 ist falsch genug. Ein Spieler mit null Punkten sieht damit genauso aus wie einer, der noch nicht gespielt hat. Das ist keine Kleinigkeit: 0 ist eine völlig normale Punktzahl, eine völlig normale Anzahl und ein völlig normaler Preis.

Dasselbe gilt für den leeren Text. Ein Nutzer, der sein Kommentarfeld absichtlich leer gelassen hat, unterscheidet sich für || nicht von einem, der gar nicht gefragt wurde.

Dafür gibt es seit 2020 ein eigenes Zeichen: ??, gesprochen Nullish Coalescing. Es greift nur bei null und undefined, also genau bei den beiden Sorten von „nichts” aus Lektion 2.6. Die Null überlebt, der leere Text überlebt, false überlebt.

Die Faustregel: Nimm ??, sobald der Wert eine Zahl oder ein Text sein könnte. || bleibt richtig, wenn wirklich jeder falsche Wert ersetzt werden soll.

Auch hier lohnen sich vier Zeilen in der Eingabezeile, weil der Unterschied genau in den Antworten liegt: 0 || 5 ist 5, 0 ?? 5 ist 0. "" || "Gast" ist "Gast", "" ?? "Gast" ist "". Die letzte Antwort sind zwei Anführungszeichen mit nichts dazwischen, und dass da überhaupt etwas steht, ist der ganze Punkt.

Ein Detail am Rande: ?? lässt sich nicht ohne Klammern mit && oder || in einer Zeile mischen. Der Browser meldet dann einen Syntaxfehler. Das ist Absicht, denn welcher der beiden zuerst greifen soll, kann niemand raten.

Kurzschluss

Kurzschluss, oder was gar nicht erst läuft
function teuer() {
  console.log("  ... teuer() wurde wirklich aufgerufen");
  return true;
}

console.log("false && teuer():");
console.log("  Ergebnis:", false && teuer());

console.log("true || teuer():");
console.log("  Ergebnis:", true || teuer());

console.log("true && teuer():");
console.log("  Ergebnis:", true && teuer());

Beide Operatoren hören auf, sobald das Ergebnis feststeht.

Bei false && irgendwas steht nach der linken Seite schon fest, dass die Antwort false lautet. Also wird die rechte Seite gar nicht erst ausgewertet. Genauso bei true || irgendwas.

Im Beispiel siehst du das daran, dass teuer() in den ersten beiden Fällen keine Zeile ausgibt. Die Funktion wurde nicht aufgerufen.

Das nennt sich Kurzschluss-Auswertung, und man nutzt es auf zwei Arten. Erstens, um teure Aufrufe zu sparen: Die billige Prüfung steht links, die aufwendige rechts. Zweitens, und das ist der wichtigere Fall, um sich abzusichern:

element && element.textContent

Wenn element null ist, wird der rechte Teil nie ausgeführt, und der TypeError aus Lektion 1.5 bleibt aus. Ab Abschnitt 10 wirst du diese Schreibweise ständig brauchen. Die modernere Fassung davon mit dem Fragezeichen kommt in Lektion 7.4, und in 10.4 siehst du sie an einem Element statt an Daten.

Zum Mitnehmen

|| greift bei jedem falschen Wert, ?? nur bei null und undefined. Der Unterschied ist die Zahl 0, und die ist öfter ein echtes Ergebnis, als man denkt.

Jetzt du

Basis Konto, kostenlos

Zu 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.