W3docs

JavaScript Nullish-Coalescing-Operator (??)

Lerne den JavaScript-Nullish-Coalescing-Operator (??), seinen Unterschied zu ||, Operatorpräzedenz sowie die logischen Zuweisungsoperatoren ??=, &&= und ||=.

Der Nullish-Coalescing-Operator (??) ist eine kurze, ausdrucksstarke Möglichkeit, in JavaScript einen Standardwert anzugeben. Er gibt seinen rechten Operanden nur zurück, wenn der linke Operand nullish ist — also null oder undefined — und gibt andernfalls den linken Wert unverändert zurück. Eingeführt in ES2020, löst er ein lang bestehendes Problem beim Einsatz des ||-Operators für Standardwerte, und er arbeitet Hand in Hand mit Optional Chaining und den logischen Operatoren, die du bereits kennst.

Was „Nullish" bedeutet

Ein Wert gilt als nullish, wenn er genau null oder undefined ist. Jeder andere Wert — einschließlich falscher Werte wie 0, '', false und NaN — wird von ?? als echter, beabsichtigter Wert behandelt.

null ?? 'default'       // 'default'
undefined ?? 'default'  // 'default'

0 ?? 'default'          // 0
'' ?? 'default'         // ''
false ?? 'default'      // false
NaN ?? 'default'        // NaN

Die Regel ist einfach: Wenn die linke Seite null oder undefined ist, erhältst du die rechte Seite; andernfalls erhältst du die linke Seite.

javascript— editable

Wie sich ?? von || unterscheidet

Das ist der wichtigste Grund für die Existenz von ??. Der logische ODER-Operator (||) gibt die rechte Seite zurück, wann immer die linke Seite irgendein falscher Wert ist — 0, '', false, NaN, null und undefined zählen alle dazu. Dieses Verhalten ist in Ordnung, bis 0 oder ein leerer string ein legitimer Wert ist, an welchem Punkt || stillschweigend das falsche Ergebnis liefert.

Betrachte einen Zähler, dessen gültiger Wert 0 sein kann:

let count = 0;

let withOr = count || 100;   // 100  — wrong! 0 got replaced
let withNullish = count ?? 100; // 0   — correct, 0 was preserved

Da 0 falsy ist, behandelt || ihn genauso wie „kein Wert" und fällt auf 100 zurück. Der ??-Operator erkennt, dass 0 nicht nullish ist, und behält ihn. Die gleiche Falle gilt für leere strings:

javascript— editable
Warnung

Greife zu ?? anstelle von ||, wann immer 0, '' oder false gültige Eingaben sind. Den ||-Operator für Standardwerte in solchen Fällen zu verwenden, ist eine der häufigsten Quellen subtiler Fehler in JavaScript — zum Beispiel, wenn eine Menge von 0 zu 1 wird oder ein leeres Suchfeld auf einen Platzhaltertext zurückfällt.

Präzedenz und Klammern

Der ??-Operator hat eine niedrige Präzedenz — etwa auf dem Niveau von || und niedriger als arithmetische und Vergleichsoperatoren. In der Praxis bedeutet dies, dass der Fallback aufgelöst wird, bevor der Wert in einem größeren Ausdruck verwendet wird, aber du solltest dennoch mit Klammern gruppieren, um die Absicht klar zu halten.

let height = null;
let width;

// Each ?? is evaluated, then the products are multiplied
let area = (height ?? 100) * (width ?? 50);
console.log(area); // 100 * 50 = 5000

Ohne die Klammern würde die Multiplikation enger binden, als man erwarten würde, daher hält das Umschließen jedes Standardwerts in ( ... ) die Mathematik eindeutig und lesbar.

?? mit && oder || zu kombinieren ist verboten

JavaScript verweigert es absichtlich, ?? mit && oder || im selben Ausdruck ohne Klammern zu mischen. Dies führt zu einem SyntaxError, da die Präzedenz zwischen ihnen mehrdeutig und leicht falsch zu lesen wäre.

// SyntaxError: Unexpected token '||'
let result = a ?? b || c;

// Fix it by grouping explicitly:
let safe = (a ?? b) || c;   // valid
let other = a ?? (b || c);  // also valid, different meaning

Die beiden gültigen Formen bedeuten unterschiedliche Dinge, weshalb die Sprache dich zwingt zu wählen. Füge die Klammern hinzu und gib genau an, was du beabsichtigst.

Hinweis

Die Einschränkung gilt nur, wenn ?? direkt neben && oder || steht. Es ist durchaus möglich, sie in separaten Ausdrücken zu verwenden, und Klammern lösen die Mehrdeutigkeit immer auf.

Logische Zuweisungsoperatoren

ES2021 hat drei logische Zuweisungsoperatoren hinzugefügt, die eine Zuweisung mit einer logischen Prüfung kombinieren. Sie weisen der linksseitigen Variable nur dann zu, wenn eine Bedingung erfüllt ist, was sie perfekt für das Setzen von Standardwerten und bedingte Aktualisierungen macht.

Nullish-Zuweisung (??=)

x ??= y weist y an x nur dann zu, wenn x aktuell null oder undefined ist. Es ist die Zuweisungsform von ?? und der häufigste der drei für das Setzen von Standardwerten auf einem object.

let settings = { theme: 'dark' };

settings.theme ??= 'light';   // already set → stays 'dark'
settings.fontSize ??= 16;     // missing → becomes 16

console.log(settings); // { theme: 'dark', fontSize: 16 }

Logische ODER-Zuweisung (||=)

x ||= y weist y an x zu, wenn x falsy ist (0, '', false, null, undefined, NaN). Wie || kann es gültige falsy-Werte überschreiben, also verwende es nur, wenn ein beliebiger falsy-Wert wirklich „ersetze mich" bedeutet.

javascript— editable

Logische UND-Zuweisung (&&=)

x &&= y weist y an x nur dann zu, wenn x truthy ist. Es ist nützlich, um einen Wert zu aktualisieren, der bereits vorhanden ist, ohne ihn zu erstellen.

let config = { token: 'abc123' };

config.token &&= config.token.trim(); // truthy → trimmed and reassigned
config.missing &&= 'never set';        // undefined → left untouched

console.log(config); // { token: 'abc123' }

Jeder Operator short-circuits ebenfalls: Er wertet die rechte Seite nur dann aus und weist zu, wenn die Bedingung es erfordert, sodass Seiteneffekte auf der rechten Seite übersprungen werden, wenn die Zuweisung nicht stattfindet.

Praxisbeispiele

Der ??-Operator glänzt überall dort, wo ein Wert legitim fehlen könnte, während 0 oder '' respektiert werden sollten. Typische Szenarien umfassen das Lesen von Konfigurationen, das Standardisieren optionaler Funktionsparameter und das Abrufen von Feldern aus API-Antworten.

// 1. Default options merged with user input
function createButton(options) {
  let label = options.label ?? 'Submit';
  let count = options.count ?? 0; // 0 stays 0, never becomes a default
  return { label, count };
}

// 2. Reading a possibly-missing API field
let response = { data: { user: { nickname: null } } };
let name = response.data.user.nickname ?? 'Guest';
console.log(name); // 'Guest'

Er funktioniert besonders gut mit Optional Chaining (?.). Optional Chaining gibt sicher undefined zurück, wenn ein Teil eines Pfads fehlt, und ?? liefert dann den Fallback in einer sauberen Zeile:

let city = user?.address?.city ?? 'Unknown';

Dies liest sich als: „Verwende die Stadt des Benutzers, wenn die gesamte Kette existiert, andernfalls verwende 'Unknown'." Für die Entscheidung, welchen von zwei Pfaden man basierend auf einer Bedingung nehmen soll, ist der bedingte (ternäre) Operator immer noch das bessere Werkzeug — ?? geht speziell darum, Standardwerte für nullish-Werte bereitzustellen.

Info

Browser-Unterstützung: ?? ist Teil von ES2020 und die logischen Zuweisungsoperatoren (??=, ||=, &&=) sind in ES2021 erschienen. Alle modernen Browser und Node.js 14+ unterstützen sie. Wenn du sehr alte Umgebungen unterstützen musst, kann ein Transpiler wie Babel sie kompilieren.

Zusammenfassung

  • ?? gibt den rechten Operanden nur zurück, wenn der linke null oder undefined ist; andernfalls gibt er den linken zurück.
  • Bevorzuge ?? gegenüber || für Standardwerte, wenn 0, '' oder false gültige Werte sind.
  • ?? hat eine niedrige Präzedenz — gruppiere mit Klammern, und platziere ?? nie direkt neben && oder || ohne Klammern (das ist ein SyntaxError).
  • ??=, ||= und &&= weisen bedingt zu: bei nullish, bei falsy und bei truthy.
  • Kombiniere ?? mit Optional Chaining (?.), um möglicherweise fehlende Daten zu lesen und in einem einzigen Ausdruck einen Standardwert anzugeben.

Teste dein Wissen

Übung
Was ergibt der Ausdruck 0 ?? 100?
Was ergibt der Ausdruck 0 ?? 100?
Übung
Warum ist das Schreiben von a ?? b || c ohne Klammern ein Problem?
Warum ist das Schreiben von a ?? b || c ohne Klammern ein Problem?
Übung
Was bewirkt user.role ??= 'member', wenn user.role undefined ist?
Was bewirkt user.role ??= 'member', wenn user.role undefined ist?
Was this page helpful?