JavaScript – Das Handbuch für die Praxis. David Flanagan
oder sind beide Operanden false, wird false zurückgegeben.
&& wird häufig zum Verbinden zweier relationaler Ausdrücke genutzt:
x === 0 && y === 0 // true nur und nur dann, wenn x und y beide 0 sind.
Da relationale Ausdrücke immer zu true oder false ausgewertet werden, liefert auch der Operator selbst true oder false, wenn er auf diese Weise verwendet wird. Relationale Operatoren haben einen höheren Vorrang als && (und ||) – Ausdrücke wie x === 0 && y === 0 können also problemlos ohne Klammern geschrieben werden.
Aber bei && müssen die Operanden nicht unbedingt boolesche Werte sein. Erinnern Sie sich einfach daran, dass alle JavaScript-Werte entweder truthy oder falsy sind. (Einzelheiten dazu finden Sie in 3.4. Die falsy-Werte sind false, null, undefined, 0, -0, NaN und "". Alle anderen Werte einschließlich aller Objekte sind truthy.) In zweiter Hinsicht kann && als UND-Operator für solche nicht-strikt wahren und falschen Werte verstanden werden. Sind beide Operanden truthy, liefert der Operator einen truthy-Wert. Andernfalls – d.h., wenn mindestens einer der Operanden ein falsy-Wert ist – liefert er einen falsy-Wert. In JavaScript können alle Ausdrücke oder Anweisungen, die einen booleschen Wert erwarten, mit nicht-strikt wahren und falschen Werten umgehen. Deswegen führt es in der Praxis zu keinerlei Problemen, dass && nicht immer true oder false liefert.
Die obige Beschreibung besagt übrigens, dass der Operator zwar einen »irgendwie wahren« Wert oder einen »irgendwie falschen« Wert liefert, aber nicht angibt, welcher Wert es genau ist. Dazu müssen wir && in dritter und letzter Hinsicht beschreiben. Der Operator beginnt bei der Auswertung mit dem ersten Operanden, dem Ausdruck auf der linken Seite. Ist der Wert dieses Operanden falsy, muss auch der Wert des gesamten Ausdrucks ein falsy-Wert sein. && liefert deswegen einfach den Wert auf der linken Seite und wertet den Ausdruck auf der rechten Seite nicht einmal mehr aus.
Ist der Wert auf der linken Seite hingegen ein truthy-Wert, hängt der Wert des gesamten Ausdrucks vom Wert auf der rechten Seite ab. Ist der Wert auf der rechten Seite ebenfalls ein truthy-Wert, ist auch der gesamte Ausdruck ein truthy-Wert. Ist der Wert auf der linken Seite dagegen ein falsy-Wert, ist auch der gesamte Ausdruck falsy. Wenn der Wert auf der linken Seite also ein truthy-Wert ist, wertet der Operator einfach den Wert auf der rechten Seite aus und liefert ihn zurück:
let o = {x: 1};
let p = null;
o && o.x // => 1: o ist truthy, es wird also der Wert von o.x geliefert.
p && p.x // => null: p ist falsy, also gib p zurück; p.x wird nicht mehr
// ausgewertet.
Entscheidend dabei ist, dass der Operand auf der rechten Seite von && manchmal ausgewertet wird und manchmal nicht. In diesem Codebeispiel hatte die Variable p den Wert null. Der Ausdruck p.x hätte, wäre er ausgewertet worden, zu einem TypeError geführt. Aber der Code nutzt && auf idiomatische Weise derart, dass p.x nur ausgewertet wird, wenn p truthy ist – und damit niemals null oder undefined.
Das Verhalten von && wird gelegentlich als »kurzschließend« bezeichnet (dieses Konzept eines vorzeitigen Abbruchs einer Auswertung ist uns bereits bei bedingten Eigenschaftszugriffen und bedingten Aufrufen begegnet), und Sie können gelegentlich auf Code stoßen, der es absichtlich einsetzt, damit Code nur bedingt ausgeführt wird. Die folgenden beiden Codezeilen haben beispielsweise die gleiche Wirkung:
if (a === b) stop(); // stop() nur aufrufen, wenn a === b.
(a === b) && stop(); // Macht das Gleiche.
Im Allgemeinen sollten Sie aufpassen, wenn Sie auf der rechten Seite von && Ausdrücke mit möglichen Seiteneffekten einsetzen (Zuweisungen, Inkremente, Dekremente, Funktionsaufrufe). Ob diese Seiteneffekte eintreten, hängt vom Wert auf der linken Seite ab.
Trotz der recht komplexen Funktionsweise dieses Operators wird er am häufigsten als einfacher logischer Operator benutzt, der mit truthy- und falsy-Werten umgehen kann.
4.10.2Logisches ODER (||)
Der ||-Operator verknüpft die beiden Operanden mit einem logischen ODER. Sind beide Operanden truthy-Werte, liefert der Operator einen truthy-Wert. Sind beide Operanden falsy-Werte, liefert der Operator einen falsy-Wert.
Obwohl der ||-Operator in der Regel meist einfach als boolescher ODER-Operator zum Einsatz kommt, weist er wie der &&-Operator ein komplexeres Verhalten auf. Der Operator beginnt bei der Auswertung mit dem ersten Operanden, dem Ausdruck auf der linken Seite. Wenn der Wert dieses ersten Operanden truthy ist, agiert der Operator »kurzschließend« und gibt den Ausdruck auf der linken Seite zurück, ohne den Ausdruck auf der rechten Seite überhaupt auszuwerten. Wenn der Wert des ersten Operanden dagegen falsy ist, wertet || den zweiten Operanden aus und gibt den Wert dieses Ausdrucks zurück.
Wie beim &&-Operator sollten Sie auf der rechten Seite Operanden vermeiden, die Nebeneffekte haben können, es sei denn, Sie möchten explizit den Umstand ausnutzen, dass der Ausdruck auf der rechten Seite eventuell nicht ausgewertet wird.
Eine sprachtypische Verwendungsweise dieses Operators ist sein Einsatz zur Auswahl des ersten wahren Werts in einer Menge von Alternativen:
// Wenn maxWidth truthy ist, nimm diesen Wert. Untersuche andernfalls
// das Objekt preferences. // Ist es nicht truthy, nimm die angegebene Konstante.
let max = maxWidth || preferences.maxWidth || 500;
Beachten Sie aber bitte, dass diese Konstruktion nur korrekt funktioniert, wenn maxWidth niemals 0 wird, da 0 ein falsy-Wert ist. Der ??-Operator (siehe 4.13.2) bietet eine Alternative.
Vor ES6 wurde dieses Idiom häufig in Funktionen verwendet, um Standardwerte für Parameter anzugeben:
// Die Eigenschaften von o auf p kopieren und p zurückgeben.
function copy(o, p) {
p = p || {}; // Wurde für p kein Objekt übergeben, nutze ein neu erstelltes.
// Hier folgt der Funktionskörper.
}
In ES6 und später wird dieser Trick jedoch nicht mehr benötigt, da der Standardwert für einen Parameter einfach in die Funktionsdefinition selbst aufgenommen werden kann: function copy(o, p={}) { … }.
4.10.3Logisches NICHT (!)
Der !-Operator ist ein unärer Operator. Er steht vor seinem einzigen Operanden und hat die Aufgabe, den logischen Wahrheitswert seines Operanden zu verneinen. Ist beispielsweise x ein truthy-Wert, wird !x zu false ausgewertet. Wenn x falsy ist, wird !x zu true ausgewertet.
Im Unterschied zu den Operatoren && und || wandelt der !-Operator seinen Operanden in einen booleschen Wert um (und nutzt dabei die in Kapitel 3 beschriebenen Regeln), bevor er den dabei erhaltenen Wert negiert bzw. umkehrt. Das heißt, dass ! immer true oder false liefert und Sie deswegen einen beliebigen Wert x in seinen zugehörigen Wahrheitswert umwandeln können, indem Sie den Operator einfach zweimal anwenden: !!x (siehe 3.9.2).
Da ! ein unärer Operator ist, hat er hohen Vorrang und bindet stark. Wenn Sie den Wert eines Ausdrucks wie p && q invertieren wollen, müssen Sie deswegen Klammern nutzen: !(p && q). Es lohnt sich, zwei Theoreme der booleschen Algebra festzuhalten, die wir auf folgende Weise in JavaScript-Syntax ausdrücken können:
// Die zwei de-morganschen Gesetze
!(p && q) === (!p || !q) // =>