Null vs. Undefined
Kostenloses Youtube-Video zum Thema
JavaScript (und durch Erweiterung TypeScript) hat zwei Untertypen: null
und undefined
. Sie sollen verschiedene Dinge bedeuten:
-
Etwas wurde nicht initialisiert:
undefined
. -
Etwas ist derzeit nicht verfügbar:
null
.
Tatsache ist, dass Sie mit beiden umgehen müssen. Interessanterweise sind in JavaScript mit ==
null
und undefined
nur gleich:
// Both null and undefined are only `==` to themselves and each other:console.log(null == null); // true (of course)console.log(undefined == undefined); // true (of course)console.log(null == undefined); // true// You don't have to worry about falsy values making through this checkconsole.log(0 == undefined); // falseconsole.log('' == undefined); // falseconsole.log(false == undefined); // false
== null
um nach beiden zu suchen undefined
oder null
. Sie möchten im Allgemeinen keinen Unterschied zwischen den beiden machen.
function foo(arg: string | null | undefined) {if (arg != null) {// arg must be a string as `!=` rules out both null and undefined.}}
Sie könnten auch
== undefined
, aber== null
ist konventioneller / kürzer.
Eine Ausnahme, root level undefined
Werte, die wir als nächstes besprechen.
Überprüfung auf Root-Ebene undefiniert
Denken Sie daran, wie ich sagte, Sie sollten == null
? Natürlich tust du das (weil ich es gerade gesagt habe ^). Verwenden Sie es nicht für Root-Level-Dinge. Wenn Sie im strikten Modus foo
und foo
undefiniert ist, erhalten Sie eine ReferenceError
Ausnahme und der gesamte Aufrufstapel wird abgewickelt.
Sie sollten den strikten Modus verwenden… tatsächlich fügt der TS-Compiler ihn für Sie ein, wenn Sie Module verwenden … mehr dazu später im Buch, damit Sie nicht explizit darüber sprechen müssen 🙂
Um zu überprüfen, ob eine Variable auf globaler Ebene definiert ist oder nicht, verwenden Sie normalerweise typeof
:
if (typeof someglobal !== 'undefined') {// someglobal is now safe to useconsole.log(someglobal);}
Beschränken Sie die explizite /h2>
Da TypeScript Ihnen die Möglichkeit gibt, Ihre Strukturen getrennt von Werten zu dokumentieren, anstatt wie folgt:
function foo(){// if Somethingreturn {a:1,b:2};// elsereturn {a:1,b:undefined};}
Sie sollten eine Typanmerkung verwenden:
function foo():{a:number,b?:number}{// if Somethingreturn {a:1,b:2};// elsereturn {a:1};}
Rückrufe im Knotenstil
Rückruffunktionen im Knotenstil (z. B. (err,somethingElse)=>{ /* something */ }
) werden im Allgemeinen mit err
auf null
ist kein Fehler. Sie verwenden im Allgemeinen sowieso nur eine Wahrheitsprüfung:
fs.readFile('someFile', 'utf8', (err,data) => {if (err) {// do something} else {// no error}});
Wenn Sie Ihre eigenen APIs erstellen, ist es in Ordnung, null
in diesem Fall aus Konsistenzgründen zu verwenden. In aller Aufrichtigkeit für Ihre eigenen APIs sollten Sie sich Versprechungen ansehen, in diesem Fall müssen Sie sich eigentlich nicht um fehlende Fehlerwerte kümmern (Sie behandeln sie mit .then
vs. .catch
).
Verwenden Sie undefined nicht als Mittel zur Bezeichnung der Gültigkeit
Zum Beispiel eine schreckliche Funktion wie diese:
function toInt(str: string) {return str ? parseInt(str) : undefined;}
kann viel besser so geschrieben werden:
function toInt(str: string): { valid: boolean, int?: number } {const int = parseInt(str);if (isNaN(int)) {return { valid: false };}else {return { valid: true, int };}}
JSON und Serialisierung
Der JSON-Standard unterstützt die Codierung null
, jedoch nicht undefined
. Wenn JSON-Codierung ein Objekt mit einem Attribut, das null
, wird das Attribut mit seinem Null-Wert enthalten sein, während ein Attribut mit einem undefined
Wert wird vollständig ausgeschlossen.
JSON.stringify({willStay: null, willBeGone: undefined}); // {"willStay":null}
Infolgedessen unterstützen JSON-basierte Datenbanken möglicherweise null
Werte, jedoch keine undefined
Werte. Da Attribute, die auf null
gesetzt sind, codiert sind, können Sie die Absicht zum Löschen eines Attributs übertragen, indem Sie seinen Wert auf null
setzen, bevor Sie das Objekt codieren und an einen Remote-Speicher übertragen.
Das Setzen von Attributwerten auf undefined kann Speicher- und Übertragungskosten sparen, da die Attributnamen nicht codiert werden. Dies kann jedoch die Semantik des Löschens von Werten im Vergleich zu fehlenden Werten komplizieren.
Abschließende Gedanken
Das TypeScript-Team verwendet null
: TypeScript-Codierungsrichtlinien nicht und hat keine Probleme verursacht. Douglas Crockford findet null
eine schlechte Idee und wir sollten alle einfach undefined
.
Die Codebasen im NodeJS-Stil verwenden jedoch null
für Fehlerargumente als Standard, da sie Something is currently unavailable
. Ich persönlich möchte nicht zwischen den beiden unterscheiden, da die meisten Projekte Bibliotheken mit unterschiedlichen Meinungen verwenden und beide mit == null
ausschließen.