Null vs. Undefined
Video youtube gratuito sull’argomento
JavaScript (e per estensione TypeScript) ha due tipi di fondo : null
e undefined
. Hanno lo scopo di significare cose diverse:
-
Qualcosa non è stato inizializzato:
undefined
. -
Qualcosa non è attualmente disponibile:
null
.
Il fatto è che dovrai occuparti di entrambi. È interessante notare che in JavaScript con ==
null
e undefined
sono solo uguali tra loro:
// 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
si Raccomanda == null
per controllare sia undefined
o null
. Generalmente non si vuole fare una distinzione tra i due.
function foo(arg: string | null | undefined) {if (arg != null) {// arg must be a string as `!=` rules out both null and undefined.}}
Si potrebbe anche fare
== undefined
, ma== null
è più convenzionale/più breve.
Un’eccezione, livello radice undefined
valori di cui discuteremo successivamente.
Verifica del livello radice non definito
Ricorda come ho detto che dovresti usare== null
? Certo che lo fai (perché l’ho appena detto ^). Non usarlo per cose a livello di root. In modalità rigorosa se si utilizzafoo
efoo
non è definito si ottiene un’eccezioneReferenceError
e l’intero stack di chiamate si svolge.
Dovresti usare la modalità rigorosa … e infatti il compilatore TS lo inserirà per te se usi i moduli … di più su quelli più tardi, nel libro, quindi non devi essere esplicito a riguardo 🙂
Quindi, per controllare se una variabile è definita o no, a livello mondiale, normalmente in uso typeof
:
if (typeof someglobal !== 'undefined') {// someglobal is now safe to useconsole.log(someglobal);}
Limite di utilizzo esplicito di non definito
a Causa del Dattiloscritto, ti dà la possibilità di documentare le proprie strutture separatamente da valori invece di roba, come:
function foo(){// if Somethingreturn {a:1,b:2};// elsereturn {a:1,b:undefined};}
si dovrebbe utilizzare un tipo di annotazione:
function foo():{a:number,b?:number}{// if Somethingreturn {a:1,b:2};// elsereturn {a:1};}
Callback stile nodo
Funzioni di callback stile nodo (ad esempio (err,somethingElse)=>{ /* something */ }
) sono generalmente chiamati con err
impostato su null
se non c’è un errore. In genere si usa comunque un controllo veritiero per questo:
fs.readFile('someFile', 'utf8', (err,data) => {if (err) {// do something} else {// no error}});
Quando si creano le proprie API, va bene usare null
in questo caso per coerenza. In tutta sincerità per le tue API dovresti guardare le promesse, in tal caso in realtà non hai bisogno di preoccuparti dei valori di errore assenti (li gestisci con .then
vs. .catch
).
Non usare undefined come mezzo per denotare la validità
Ad esempio una funzione terribile come questa:
function toInt(str: string) {return str ? parseInt(str) : undefined;}
può essere scritta molto meglio in questo modo:
function toInt(str: string): { valid: boolean, int?: number } {const int = parseInt(str);if (isNaN(int)) {return { valid: false };}else {return { valid: true, int };}}
JSON e serializzazione
Lo standard JSON supporta la codificanull
ma nonundefined
. Quando JSON codifica un oggetto con un attributo che ènull
, l’attributo sarà incluso con il suo valore null, mentre un attributo con unundefined
valore sarà escluso del tutto.
JSON.stringify({willStay: null, willBeGone: undefined}); // {"willStay":null}
Di conseguenza, i database basati su JSON possono supportarenull
valori ma nonundefined
valori. Poiché gli attributi impostati su null
sono codificati, è possibile trasmettere l’intento di cancellare un attributo impostando il suo valore su null
prima di codificare e trasmettere l’oggetto a un archivio remoto.
L’impostazione dei valori degli attributi su undefined consente di risparmiare sui costi di archiviazione e trasmissione, poiché i nomi degli attributi non verranno codificati. Tuttavia, ciò può complicare la semantica dei valori di compensazione rispetto ai valori assenti.
Considerazioni finali
TypeScript team non utilizzanull
: Linee guida di codifica TypeScript e non ha causato alcun problema. Douglas Crockford pensa che null
sia una cattiva idea e dovremmo usare tutti undefined
.
Tuttavia, le basi di codice in stile NodeJS utilizzanonull
per gli argomenti di errore come standard in quanto denotaSomething is currently unavailable
. Personalmente non mi interessa distinguere tra i due poiché la maggior parte dei progetti utilizza librerie con opinioni diverse e esclude entrambi con == null
.