Contrairement à de nombreux autres langages, il existe en JavaScript deux entités différentes qui représentent l'absence d'une valeur (qui ait un sens). Ce sont null et undefined.
nullLa valeur primitive null sert de « valeur vide » intentionnelle pour une variable.
Dans d'autres langages, une construction similaire ne sert parfois qu'à des objets (absents) ou à des types pointeur.
En JavaScript, null représente généralement une valeur vide, quel que soit le type.
let name = null;
// name is intentionally set to "empty" because it is not
// available
Pour vérifier qu'une variable vaut null, tu peux utiliser l'opérateur d'égalité stricte ===.
Bien que null soit une valeur primitive, l'opérateur typeof renvoie « à tort » object, pour des raisons historiques.
Cela signifie qu'il ne peut pas être utilisé seul pour vérifier qu'une variable vaut null.
let name = null;
name === null;
// => true
// Pitfall:
typeof name;
// => 'object'
undefinedUne variable à laquelle aucune valeur n'a été affectée est de type
undefined.1
Autrement dit, tandis que null représente une valeur vide (mais une valeur quand même), undefined représente l'absence totale de valeur. 🤯
undefined apparaît dans différents contextes.
undefined.undefined.undefined.undefined, sauf si cet argument a une valeur par défaut.let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
Pour vérifier qu'une variable vaut undefined, tu peux utiliser l'opérateur d'égalité stricte === ou l'opérateur typeof.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
Il n'est pas recommandé d'affecter undefined manuellement à une variable : utilise plutôt null, pour bien montrer que tu définis une valeur vide intentionnellement.
Comme mentionné plus haut, accéder à une clé inexistante dans un objet renvoie undefined en JavaScript.
Cependant, si tu essaies de récupérer une valeur imbriquée alors que la clé parente n'existe pas, l'évaluation de la clé imbriquée se fait sur undefined, ce qui provoque TypeError: Cannot read property ... of undefined.
En théorie, il faudrait donc toujours vérifier que la clé parente existe avant de pouvoir récupérer la clé imbriquée.
On le faisait souvent avec l'opérateur ET &&, mais pour des valeurs profondément imbriquées, cela donne des expressions très longues.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
Pour résoudre ce problème, le chaînage optionnel a été ajouté à la spécification du langage en 2020.
Avec l'opérateur de chaînage optionnel ?., tu peux faire en sorte que JavaScript n'essaie d'accéder à la clé imbriquée que si la clé parente n'était ni null ni undefined.
Sinon, c'est undefined qui est renvoyé.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.residence;
// => undefined
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
obj.residence?.street?.number;
// => undefined
Il arrive que tu veuilles appliquer une valeur par défaut au cas où une variable serait null ou undefined.
Par le passé, on utilisait souvent pour cela un opérateur ternaire ?, ou bien l'évaluation paresseuse de l'opérateur OU ||.
Cela a l'inconvénient d'appliquer la valeur par défaut dans tous les cas où la variable est falsy (par exemple '' ou 0), et pas seulement lorsqu'elle est null ou undefined.
Cela peut facilement produire des résultats inattendus.
let amount = null;
amount = amount || 1;
// => 1
amount = 0;
amount = amount || 1;
// => 1
amount = 0;
amount ? amount : 1;
// => 1
Pour y remédier, l'opérateur de coalescence des nuls ?? a été introduit.
Comme le chaînage optionnel, il a été ajouté à la spécification du langage en 2020.
L'opérateur de coalescence des nuls ?? ne renvoie l'opérande de droite que lorsque l'opérande de gauche vaut null ou undefined.
Sinon, c'est l'opérande de gauche qui est renvoyé.
On peut donc désormais appliquer une valeur par défaut de façon plus précise.
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (consulté le 4 juin 2021).