Opérateur de coalescence des nuls (Nullish coalescing operator)
L'opérateur de coalescence des nuls (??
), est un opérateur logique qui renvoie son opérande de droite lorsque son opérande de gauche vaut null
ou undefined
et qui renvoie son opérande de gauche sinon.
Contrairement à l'opérateur logique OU (||
), l'opérande de gauche sera renvoyé s'il s'agit d'une valeur équivalente à false
qui n'est ni null
, ni undefined
. En d'autres termes, si vous utilisez ||
pour fournir une valeur par défaut à une variable foo
, vous pourriez rencontrer des comportements inattendus si vous considérez certaines valeurs falsy comme utilisables (par exemple une chaine vide ''
ou 0
). Voir ci-dessous pour plus d'exemples.
Exemple interactif
Syntaxe
leftExpr ?? rightExpr;
Exemples
Utilisation de l'opérateur de coalescence des nuls
Dans cet exemple, nous fournirons des valeurs par défaut mais conserverons des valeurs autres que null
ou undefined
.
const valeurNulle = null;
const texteVide = ""; // falsy
const unNombre = 42;
const valA = valeurNulle ?? "valeur par défaut pour A";
const valB = texteVide ?? "valeur par défaut pour B";
const valC = unNombre ?? 0;
console.log(valA); // "valeur par défaut pour A"
console.log(valB); // "" (car la chaine vide n'est ni `null` ni `undefined`)
console.log(valC); // 42
Affectation d'une valeur par défaut à une variable
Auparavant, lorsque l'on voulait attribuer une valeur par défaut à une variable, une solution fréquente consistait à utiliser l'opérateur logique OU (||
) :
let toto;
// toto ne se voit jamais attribuer de valeur, il vaut donc undefined
let unTexteBateau = toto || "Coucou !";
Cependant, parce que ||
est un opérateur logique booléen, l'opérande de gauche a été converti en un booléen pour l'évaluation et aucune valeur falsy (0
, ''
, NaN
, null
, undefined
) n'a été renvoyée. Ce comportement peut entraîner des conséquences inattendues si on souhaite considérer 0
, ''
ou NaN
comme des valeurs valides.
let compteur = 0;
let texte = "";
let qté = compteur || 42;
let message = texte || "Coucou !";
console.log(qté); // 42 et non 0
console.log(message); // "Coucou !" et non ""
L'opérateur de coalescence des nuls évite ce risque en ne renvoyant le deuxième opérande que lorsque le premier vaut null
ou undefined
(mais pas d'autres valeurs falsy) :
let monTexte = ""; // Un chaine vide (qui est donc une valeur falsy)
let notFalsyText = monTexte || "Hello world";
console.log(notFalsyText); // Hello world
let preservingFalsy = monTexte ?? "Salut le voisin";
console.log(preservingFalsy); // '' (car monTexte n'est ni null ni undefined)
Court-circuitage
À l'instar des opérateurs logiques OR (||
) et AND (&&
), l'expression de droite n'est pas évaluée si celle de gauche ne vaut ni null
ni undefined
.
function A() {
console.log("A a été appelée");
return undefined;
}
function B() {
console.log("B a été appelée");
return false;
}
function C() {
console.log("C a été appelée");
return "toto";
}
console.log(A() ?? C());
// Inscrit "A a été appelée" puis "C a été appelée" et enfin "toto"
// puisque : A() retourne undefined, les deux expressions sont donc évaluées
console.log(B() ?? C());
// Inscrit "B a été appelée" puis false
// puisque : B() retourne false (et non null ou undefined) et
// l'opérande de droite n'est pas évaluée
Pas de chaînage possible avec les opérateurs AND ou OR
Il n'est pas possible de combiner les opérateurs AND (&&
) ou OR (||
) directement avec l'opérateur de coalescence des nuls (??
). Un tel cas lèverait une exception SyntaxError
.
null || undefined ?? "toto"; // soulève une SyntaxError
true || undefined ?? "toto"; // soulève une SyntaxError
Cependant, fournir des parenthèses pour indiquer explicitement la priorité est correct :
(null || undefined) ?? "toto"; // Renvoie "toto"
Relation avec l'opérateur de chaînage optionnel (?.
)
Tout comme l'opérateur de coalescence des nuls, l'opérateur de chaînage optionnel (?.) traite les valeurs null
et undefined
comme des valeurs spécifiques. Ce qui permet d'accéder à une propriété d'un objet qui peut être null
ou undefined
.
let toto = { uneProprieteToto: "coucou" };
console.log(toto.uneProprieteToto?.toUpperCase()); // "COUCOU"
console.log(toto.uneProprieteTiti?.toUpperCase()); // undefined
Spécifications
Specification |
---|
ECMAScript Language Specification # prod-CoalesceExpression |
Compatibilité des navigateurs
BCD tables only load in the browser