Null vs Undefined
Vidéo youtube gratuite sur le sujet
JavaScript (et par extension TypeScript) a deux types de fond: null
et undefined
. Ils sont destinés à signifier différentes choses:
-
Quelque chose n’a pas été initialisé:
undefined
. -
Quelque chose est actuellement indisponible:
null
.
Le fait est que vous devrez gérer les deux. Fait intéressant en JavaScript avec ==
null
et undefined
ne sont égaux que les uns aux autres :
// 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
Recommander == null
pour vérifier à la fois undefined
ou null
. Vous ne voulez généralement pas faire de distinction entre les deux.
function foo(arg: string | null | undefined) {if (arg != null) {// arg must be a string as `!=` rules out both null and undefined.}}
Vous pouvez également faire
== undefined
, mais== null
est plus conventionnel / plus court.
Une exception, niveau racine undefined
valeurs dont nous discuterons ensuite.
Vérification du niveau racine non défini
Rappelez-vous comment j’ai dit que vous devriez utiliser == null
? Bien sûr que oui (parce que je viens de le dire ^). Ne l’utilisez pas pour les choses au niveau racine. En mode strict, si vous utilisez foo
et que foo
n’est pas défini, vous obtenez une exception ReferenceError
et que toute la pile d’appels se déroule.
Vous devez utiliser le mode strict… et en fait, le compilateur TS l’insérera pour vous si vous utilisez des modules… plus d’informations sur celles-ci plus loin dans le livre afin que vous n’ayez pas à être explicite à ce sujet:)
Donc pour vérifier si une variable est définie ou non au niveau global, vous utilisez normalement typeof
:
if (typeof someglobal !== 'undefined') {// someglobal is now safe to useconsole.log(someglobal);}
Limitez l’utilisation explicite d’undefined
Car TypeScript vous donne la possibilité de documenter vos structures séparément des valeurs au lieu de choses comme:
function foo(){// if Somethingreturn {a:1,b:2};// elsereturn {a:1,b:undefined};}
vous devez utiliser une annotation de type:
function foo():{a:number,b?:number}{// if Somethingreturn {a:1,b:2};// elsereturn {a:1};}
Les fonctions de rappel de style de nœud
Les fonctions de rappel de style de nœud (par exemple (err,somethingElse)=>{ /* something */ }
) sont généralement appelées avec err
définies sur null
s’il n’y a pas d’erreur. Vous utilisez généralement une vérification véridique pour cela de toute façon:
fs.readFile('someFile', 'utf8', (err,data) => {if (err) {// do something} else {// no error}});
Lors de la création de vos propres API, il est acceptable d’utiliser null
dans ce cas pour la cohérence. En toute sincérité pour vos propres API, vous devriez regarder les promesses, dans ce cas, vous n’avez pas besoin de vous soucier des valeurs d’erreur absentes (vous les gérez avec .then
vs. .catch
).
N’utilisez pas undefined comme moyen de désigner la validité
Par exemple, une fonction horrible comme celle-ci:
function toInt(str: string) {return str ? parseInt(str) : undefined;}
peut être beaucoup mieux écrite comme ceci:
function toInt(str: string): { valid: boolean, int?: number } {const int = parseInt(str);if (isNaN(int)) {return { valid: false };}else {return { valid: true, int };}}
JSON et sérialisation
La norme JSON prend en charge l’encodage null
mais pas undefined
. Lors de l’encodage JSON d’un objet avec un attribut null
, l’attribut sera inclus avec sa valeur null, tandis qu’un attribut avec une valeur undefined
sera entièrement exclu.
JSON.stringify({willStay: null, willBeGone: undefined}); // {"willStay":null}
Par conséquent, les bases de données basées sur JSON peuvent prendre en charge les valeurs null
mais pas les valeurs undefined
. Étant donné que les attributs définis sur null
sont codés, vous pouvez transmettre l’intention d’effacer un attribut en définissant sa valeur sur null
avant d’encoder et de transmettre l’objet à un magasin distant.
Définir les valeurs d’attribut sur undefined permet d’économiser sur les coûts de stockage et de transmission, car les noms d’attribut ne seront pas codés. Cependant, cela peut compliquer la sémantique de la compensation des valeurs par rapport aux valeurs absentes.
Pensées finales
L’équipe TypeScript n’utilise pas null
: Directives de codage TypeScript et cela n’a causé aucun problème. Douglas Crockford pense que null
est une mauvaise idée et nous devrions tous utiliser undefined
.
Cependant, les bases de code de style NodeJS utilisent null
pour les arguments d’erreur en standard car ils dénotent Something is currently unavailable
. Personnellement, je ne me soucie pas de faire la distinction entre les deux car la plupart des projets utilisent des bibliothèques avec des opinions différentes et excluent simplement les deux avec == null
.