Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Nullish coalescing operator - Erklärt 🇩🇪 (german only)
Thomas Scharke
Thomas Scharke

Posted on • Edited on

     

Nullish coalescing operator - Erklärt 🇩🇪 (german only)

DerNullish coalescing operator ist ein neuer und zusätzlicher JavaScript-Operator, der seit Juni 2020 mit ECMAScript 2020 (ES2020) der Programmiersprache zur Verfügung steht.

Er ist neben den (vielleicht) bekanntenbinären logischen Operatoren (Binary Logical Operators)&& (UND) und|| (ODER) der drittenicht binäre Operator und hat die Schreibweise??.

Zum Einsatz kommt er immer dann, wenn ich explizit prüfen möchte ob der Wert einer Variable vorliegt um diesen zu nutzen oder, wenn der Wert nicht vorliegt, mit einem anderen Wert weiter zu arbeiten.

Hier für mich der "Klassiker": Einmal mit einemif-Block, dann in einer "vereinfachten" Schreibweise mit demODER-Operator und zu guter letzt in der Schreibweise mit dem neuenNullish coalescing operator.

// Long versionletsecondValue="DEFAULT_VALUE";if(firstValue!==null&&firstValue!==undefined&&firstValue!==""){secondValue=firstValue;}// Shorthand with OR-OperatorsecondValue=firstValue||"DEFAULT_VALUE";// With Nullish-OperatorsecondValue=firstValue??"DEFAULT_VALUE";
Enter fullscreen modeExit fullscreen mode

Die erste Vereinfachung, mit demODER-Operator, funktioniert in den meisten Fällen, deckt jedochnicht den Fall ab mit bool‘schen Werten zu arbeiten.

Doch gehen wir es Schritt für Schritt durch und schauen erstmal warum die Varianten mit demODER-Operator funktioniert um dann auf den meist "besseren"Nullish coalescing operator auszuweichen.

ODER-Operator

Der binäre logische Operator (Binary Logical Operator)|| (ODER) ist wie folgt definiert:

{Ausdruck linke Seite}|| {Ausdruck rechte Seite}

D.h. liefert der Ausdruck auf der linken Seite den Wertfalse wird der Ausdruck auf der rechten Seite interpretiert, ansonsten wird der Ausdruck der linken Seite interpretiert.

Für unsere "Vereinfachung" von oben…

letsecondValue=firstValue||"DEFAULT_VALUE";
Enter fullscreen modeExit fullscreen mode

bedeutet es, dass wenn die VariablefirstValue den Werttrue liefert, wird dieser Wert zurückgegeben (und in diesem Fall der VariablensecondValue zugewiesen). Liefert die VariablefirstValue allerdingsfalse wird der Wert der rechten Seite der VariablesecondValue zugewiesen - in meinem Fall also der WertDEFAULT_VALUE.

Schritt für Schritt

Gehen wir mein obiges Beispiel Schritt für Schritt durch und schauen was ich meine mit…

Die erste Vereinfachung, mit demODER-Operator, funktioniert in den meisten Fällen, deckt jedochnicht den Fall ab mit bool‘schen Werten zu arbeiten.

und wie uns derNullish coalescing operator hier hilft.

Dazu packe ich mein Beispiel in eine Funktion und führe diese anschließend aus:

functiondoSomethingAmazing(firstValue){letsecondValue="DEFAULT_VALUE";if(firstValue!==null&&firstValue!==undefined&&firstValue!==""){// Do somthing greatesecondValue=firstValue;}returnsecondValue;}doSomethingAmazing(1);// 1 ✅doSomethingAmazing(42);// 42 ✅doSomethingAmazing(null);// DEFAULT_VALUE ✅doSomethingAmazing("");// DEFAULT_VALUE ✅doSomethingAmazing(/* No value means `undefined` as value */);// DEFAULT_VALUE ✅doSomethingAmazing(true);// true ✅doSomethingAmazing(false);// false ✅
Enter fullscreen modeExit fullscreen mode

🥳 Alles wunderbar und der Code funktioniert auch mit bool'schen Werten. 🥳

Reflexartig setzt bei mir das Gefühl ein diesen Code zu "vereinfachen" und die Möglichkeiten von JavaScript für mich zu nutzen. Denn dass ein Wert vorhanden ist kann ich mit einemif (firstValue) ermitteln, was zu dieser Version meines Codes führt:

functiondoSomethingAmazing(firstValue){letsecondValue="DEFAULT_VALUE";if(firstValue){secondValue=firstValue;}returnsecondValue;}doSomethingAmazing(1);// 1 ✅doSomethingAmazing(42);// 42 ✅doSomethingAmazing(null);// DEFAULT_VALUE ✅doSomethingAmazing("");// DEFAULT_VALUE ✅doSomethingAmazing(/* No value means `undefined` as value */);// DEFAULT_VALUE ✅doSomethingAmazing(true);// true ✅doSomethingAmazing(false);// DEFAULT_VALUE ❌ 😮
Enter fullscreen modeExit fullscreen mode

😮 Upps…Wenn ich einfalse an die Funktion übergebe erhalte ich den WertDEFAULT_VALUE zurück und nicht wie erwartet den Wertfalse 🤔

Ich gehe noch einen Schritt weiter und "vereinfachen" meinen Code noch einmal; und dieses mal nutze ich denODER-Operator:

functiondoSomethingAmazing(firstValue){// Executes the right operand ("DEFAULT_VALUE")// only if the left operand (firstValue) is falsy// Dieser Einzeiler wird auch short-circuiting operator genannt 😃letsecondValue=firstValue||"DEFAULT_VALUE";returnsecondValue;}doSomethingAmazing(1);// 1 ✅doSomethingAmazing(42);// 42 ✅doSomethingAmazing(null);// DEFAULT_VALUE ✅doSomethingAmazing("");// DEFAULT_VALUE ✅doSomethingAmazing(/* No value means `undefined` as value */);// DEFAULT_VALUE ✅doSomethingAmazing(true);// true ✅doSomethingAmazing(false);// DEFAULT_VALUE ❌ 😮
Enter fullscreen modeExit fullscreen mode

Die letzte "Vereinfachung" meines Codes finde ich noch besser. Diese nimmt mir denif-Block und macht den Code einfacher zu lesen und übersichtlicher.

Doch beide "Vereinfachung" führen zu dem selben unerwarteten Ergebnis, wenn ich die Funktion mit dem Wertfalse aufrufe.

Was habe ich kaputt gemacht? 🤔

Ich habe nichts wirklichkaputt gemacht. Ich habe lediglich, in beiden Vereinfachungen, Funktionalität von JavaScript genutzt die davon ausgeht dass ein Wert falsch (false) sein muss - alsofalsy ist. Im konkret Fall, mit meinemif-Block und demODER-Operator, prüfe ich ob der WertfirstValue falsch ist um dann den WertDEFAULT_VALUE zu nutzen.

Wann ist ein Wert "falsy"

In JavaScript ist ein Wert genau dann falsch (false) oderfalsy wenn diesernull,undefined,0 oderfalse ist.

Und da dieses in JavaScript nunmal so ist, habe ich mit meiner "Vereinfachung" des Codes auch gleich dasVerhalten meiner Implementierung verändert 🤷‍

Rufe doch die letzten beiden Codebeispiele mal mit0 (Zero) auf:

doSomethingAmazing(0);
Enter fullscreen modeExit fullscreen mode

Auch hier möchte ich dass mir der Wert0 (Zero) zurückgegeben wird, doch ich erhalte - logischerweise - den WertDEFAULT_VALUE 🤷‍

Doch kommen wir zurück zur eigentlich Implementierung mit folgendem Ausdruck imif-Block:

firstValue!==null&&firstValue!==undefined&&firstValue!=="")
Enter fullscreen modeExit fullscreen mode

Daraus leitet sich meine Anforderung ab dass ich prüfen möchte ob ein Wertnullish ist undnicht ob ein Wertfalsy ist, wie ich es durch meine "Vereinfachungen" (unwissentlich) gemacht habe.

Was heisstnullish

Mitnullish ist gemeint dass ein Ausdruck die Wertenull oderundefined haben muss, nur dann ist ernullish.

Und genau dieses ist und war es, was ich mit meiner ersten Implementierung haben wollte und umgesetzt habe.

Kann ich jetzt meine einleitendes Beipiels nicht "vereinfachen"? Muss ich, von Hand, allenullish-Werte in JavaScript selber abfragen?

😱😱😱N E I N 😱😱😱

Der Neue - Nullish coalescing operator (??)

Hier kommtder Neue ins Spiel - der dritten logische Operatoren in JavaScript.

Meine Damen und Herren derNullish coalescing operator 🚀🚀🚀, der in JavaScript als?? geschrieben wird und wie folgt definiert ist:

{Ausdruck linke Seite}?? {Ausdruck rechte Seite}

Dieser Operator verhält sich ähnlich wie derODER-Operator, doch mit dem entscheidenden Unterschied…

Es wird geprüft ob der Ausdruck auf der linken Seite"nullish" ist.

Und nicht wie beimODER-Operator, ob der Ausdruckfalse ist.

Ein paarBeispiele zumNullish coalescing operator:

1??"DEFAULT VALUE";// Result is: 1 ✅42??"DEFAULT VALUE";// Result is: 42 ✅null??"DEFAULT VALUE";// Result is: DEFAULT VALUE ✅undefined??"DEFAULT VALUE";// Result is: DEFAULT VALUE ✅true??"DEFAULT VALUE";// Result is: true ✅false??"DEFAULT VALUE";// Result is: false ✅0??"DEFAULT VALUE";// Result is: 0 ✅""??"DEFAULT VALUE";// Result is: "" ❓
Enter fullscreen modeExit fullscreen mode

Und mit diesem Wissen kann ich mein Codebeispiel auch wieder "vereinfachen" - und zwar so…

functiondoSomethingAmazing(firstValue){// Executes the right operand ("DEFAULT_VALUE")// only if the left operand (firstValue) is nullishletsecondValue=firstValue??"DEFAULT_VALUE";returnsecondValue;}doSomethingAmazing(1);// 1 ✅doSomethingAmazing(42);// 42 ✅doSomethingAmazing(null);// DEFAULT_VALUE ✅doSomethingAmazing(/* No value means `undefined` as value */);// DEFAULT_VALUE ✅doSomethingAmazing(true);// true ✅doSomethingAmazing(false);// false ✅doSomethingAmazing("");// "" ❓
Enter fullscreen modeExit fullscreen mode

Einen habe ich noch…

Bei meinen Beispielen mit demNullish coalescing operator wird Euch aufgefallen sein, dass der Aufruf meiner "vereinfachten" Funktionen mit einem leeren String ("") nicht dazu führt das mirDEFAULT_VALUE zurückgegeben wird.

Das ist für die Funktionsweise meines Beispiels nicht relevant, doch ich möchte Euch nicht verschweigen warum es dazu kommt.

Die Antwort liegt eigentlich klar vor uns: DerNullish coalescing operator (??) prüft ob ein Wertnullish ist, alsonull oderundefined ist. Und ein leerer String ("") ist in JavaScript ein leerer String und damit wedernull nochundefined - aberfalsy 🤣

Ein weiteres Beispiel

Gehen wir noch einen Schritt weiter und wollen dieses mal tatsächlich mit bool‘schen Werten wietrue undfalse arbeiten. Sagen wir, im Rahmen einer Konfiguration die genau dann einen Lebenszeichen von sich geben soll wenn wir online sind und voraussetzt dass wir (immer) online sind (per default):

functiondoSomethingAmazingWithAConfiguration({online}){// We use the OR operatorletsendKeepAlive=online||true;returnsendKeepAlive;}// We say explicit that we're onlinedoSomethingAmazingWithAConfiguration({online:true});// true ✅// We use the default-statedoSomethingAmazingWithAConfiguration({});// true ✅// We say explicit that we're offline ⚠️doSomethingAmazingWithAConfiguration({online:false});// true ❌ 😮
Enter fullscreen modeExit fullscreen mode

An dieser Stelle des Textes habe ich jetzt mit dem "falschen" Rückgabewert des letzten Aufrufes der Funktion gerechnet, doch es ist nicht das was ich wollte.

Ich möchte das der Rückgabewert der Funktion mirfalse liefert, wenn wir offline sind, also wenn wir im übergebenem Objekt den keyonline auffalse setzen ({ online: false }).

Das bekannte Problem

Mit dem gelernten macht dieses falsche Ergebnis meines Funktionsaufrufes Sinn. Dennonline || true hat mit dem letzten Aufruf folgende Werte:false || true.

Und wenn die linke Seite desODER-Operatorsfalse liefert wird der Wert des Ausdrucks auf der rechten Seite genutzt (der Wert der linken Seite istfalsy) - in unserem Falltrue 🤷‍.

Der Code funktioniert genau wie geschrieben, doch nicht wie erwartet.

Mögliche Lösungen

Für meine Funktion, die ein Konfigurationsobjekt erwartet, könnte ich mitDestructuring arbeiten und einen Defaultwert definieren:

functiondoSomethingAmazingWithAConfiguration({online}={online:false}){returnonline;}
Enter fullscreen modeExit fullscreen mode

Oder ich nutze, statt eines Konfigurationsobjekts, einboolean und prüfe diese mit demstrict inequality operator (!==):

functiondoSomethingAmazingWithAConfiguration({online}){letsendKeepAlive=online!==false;returnsendKeepAlive;}
Enter fullscreen modeExit fullscreen mode

Doch in diesem Artikel ist derNullish coalescing operator der Star 🤩 und für meine Konfigurationsfunktion auch eine Lösung:

functiondoSomethingAmazingWithAConfiguration({online}){// We use the Nullish coalescing operatorletsendKeepAlive=online??true;returnsendKeepAlive;}// We say explicit that we're onlinedoSomethingAmazingWithAConfiguration({online:true});// true ✅// We use the default-statedoSomethingAmazingWithAConfiguration({});// true ✅// We say explicit that we're offlinedoSomethingAmazingWithAConfiguration({online:false});// false ✅
Enter fullscreen modeExit fullscreen mode

Anmerkung

Diesen Artikel habe ich bewusst in meiner Muttersprache (Deutsch) verfasst, da es eine sehr aktive deutsche JavaScript-Community (u.a.hier) gibt von der ich ein Teil bin und der ich hiermit etwas zurück geben möchte 🙇‍♂️

Oder um es mit mit dem Hashtag meines Trainer-BuddiesWebDave zu sagen:#CommunityRocks und in diesem Fall#GermanJavaScriptCommunityRocksToo 😉🚀😎

If you want to read this article in English, you are in the right placehere

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

PASSIONATE IMPLEMENTER OF IDEAS
  • Location
    🌍
  • Work
    Software Artist • Freelancer • Trainer • Guide • Remote Worker
  • Joined

More fromThomas Scharke

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp