Menu
Français

Opérateur ?? en JavaScript : bien gérer les valeurs par défaut

Comment l'opérateur ?? applique une valeur par défaut uniquement quand la variable vaut null ou undefined — et pourquoi c'est plus fiable que || dans la vraie vie.

Une valeur par défaut plus intelligente

En JavaScript, on a longtemps utilisé value || fallback pour gérer les valeurs par défaut. Ça marche la plupart du temps, mais il y a un piège : tout ce qui est falsy est considéré comme absent. Autrement dit, 0, '' et false déclenchent la valeur de repli, même quand c'est exactement ce qu'on voulait garder.

C'est là qu'intervient l'opérateur ?? de coalescence des nuls (nullish coalescing, arrivé avec ES2020). Il ne bascule sur la valeur par défaut que si l'on a affaire à null ou undefined :

index.js
Output
Click Run to see the output here.

0 et '' passent le filtre. null et undefined, eux, sont remplacés. Tout l'opérateur tient là-dedans.

Pourquoi || ne suffit pas

Voici le bug classique que ?? est justement venu corriger :

index.js
Output
Click Run to see the output here.

L'utilisateur a demandé un volume à 0 (silence) et un pseudo vide. Les deux ont été écrasés discrètement parce que || est incapable de faire la différence entre « absent » et « falsy ».

Passons à ?? :

index.js
Output
Click Run to see the output here.

Maintenant, 0 et '' passent sans être modifiés, et seuls les champs réellement absents reçoivent la valeur par défaut. C'est quasiment toujours ce que vous cherchez à faire.

Le modèle mental à retenir

?? pose une seule question : la valeur de gauche est-elle null ou undefined ? Rien d'autre ne compte.

Valeur de gaucheleft || right renvoieleft ?? right renvoie
nullrightright
undefinedrightright
0rightleft (0)
''rightleft ('')
falserightleft (false)
NaNrightleft (NaN)
n'importe quel objetleftleft

Optez pour ?? quand vos données contiennent des valeurs falsy qui ont du sens. Optez pour || quand vous voulez vraiment rejeter toutes les valeurs falsy (chaînes vides, compteurs à zéro, etc.) — ce cas existe, mais il est bien moins fréquent qu'on ne le croit.

Le court-circuit

Comme || et &&, l'opérateur ?? fonctionne en court-circuit. Si la valeur de gauche n'est pas nullish, la partie de droite n'est même pas évaluée :

index.js
Output
Click Run to see the output here.

expensiveDefault() ne s'exécute qu'une seule fois — pour b. Pratique quand le fallback est un appel de fonction, une requête réseau, ou n'importe quoi qu'on préfère éviter tant que ce n'est pas nécessaire.

Combiner ?? avec le chaînage optionnel

Les opérateurs ?? et ?. ont été introduits ensemble dans ES2020, et ils sont pensés pour fonctionner en duo. Le chaînage optionnel parcourt un chemin potentiellement absent et renvoie undefined dès qu'une étape manque ; la coalescence des nuls prend alors le relais pour fournir une valeur par défaut cohérente :

index.js
Output
Click Run to see the output here.

Sans ce duo, le même code se transforme en une horrible cascade de vérifications && ou en try/catch. Avec eux, l'accès sécurisé et les valeurs par défaut tiennent sur une seule ligne.

L'affectation nullish : ??=

a ??= b affecte b à a uniquement quand a vaut null ou undefined. C'est l'opérateur d'affectation logique nullish, et il fonctionne en court-circuit : si a a déjà une valeur, l'expression à droite n'est même pas évaluée.

index.js
Output
Click Run to see the output here.

Remarquez que verbose: false et retries: 0 sont bien conservés — ??= ne remplit que ce qui manque réellement. À comparer avec ||=, qui écraserait les deux.

Priorité des opérateurs et la règle des parenthèses

?? refuse volontairement d'être mélangé avec || ou && sans parenthèses. Le code suivant déclenche une SyntaxError :

const x = a || b ?? c;   // SyntaxError

Les concepteurs du langage ont estimé que la priorité des opérateurs était suffisamment ambiguë pour t'obliger à lever le doute. Il suffit d'ajouter des parenthèses et tout roule :

index.js
Output
Click Run to see the output here.

Des regroupements différents donnent des résultats différents. Les parenthèses ne sont pas là pour faire joli — elles indiquent aux futurs lecteurs (et au parseur) ce que tu voulais vraiment dire.

À ne pas confondre avec une valeur par défaut dans les paramètres

Les paramètres par défaut d'une fonction suivent leur propre logique : ils ne s'appliquent que si l'argument vaut undefined, pas null. C'est une nuance importante par rapport à l'opérateur ??, qui, lui, traite les deux de la même manière.

index.js
Output
Click Run to see the output here.

Si tu veux que null déclenche aussi la valeur par défaut, utilise ?? directement dans le corps de la fonction :

index.js
Output
Click Run to see the output here.

Petite nuance, facile à rater quand une API te renvoie null pour dire « aucune valeur définie ».

Quand utiliser l'opérateur ?? en JavaScript

Prends ?? comme opérateur par défaut, sauf si tu as une vraie raison de faire autrement. C'est celui qui colle le mieux au comportement réel des données : 0, '' et false sont le plus souvent des valeurs légitimes qu'il faut conserver, et seule une donnée vraiment absente mérite une valeur de repli. Garde || pour les cas où tu veux réellement remplacer n'importe quelle valeur falsy.

La suite : les classes

Voilà, c'est bouclé pour les objets et les tableaux — tu as maintenant de quoi construire et parcourir tes structures de données en toute sécurité. Le prochain chapitre s'attaque à l'organisation du comportement : les classes, l'héritage et le système de prototypes qui tourne en dessous.

Questions fréquentes

C'est quoi l'opérateur de coalescence des nuls en JavaScript ?

?? renvoie son opérande de droite uniquement si celui de gauche vaut null ou undefined. Dans tous les autres cas, il renvoie la valeur de gauche telle quelle. Autrement dit, value ?? fallback est la façon propre de définir une valeur par défaut sans se faire piéger par des valeurs falsy légitimes comme 0 ou ''.

Quelle différence entre ?? et || en JavaScript ?

|| bascule sur l'alternative dès qu'on rencontre une valeur falsy — 0, '', false, NaN, null, undefined. ??, lui, ne bascule que sur null et undefined. Si 0 ou une chaîne vide sont des valeurs valides dans tes données, il faut utiliser ??. Si au contraire tu veux vraiment écarter toutes les valeurs falsy, || reste le bon choix.

Peut-on combiner la coalescence des nuls avec le chaînage optionnel ?

Oui, et c'est même un duo très classique. user?.settings?.theme ?? 'light' parcourt la chaîne en toute sécurité, renvoie undefined si un maillon est absent, puis retombe sur 'light'. Les deux opérateurs ont d'ailleurs été livrés ensemble dans ES2020, précisément pour ce genre d'usage.

À quoi sert l'opérateur ??= ?

a ??= b affecte b à a seulement si a vaut null ou undefined. C'est l'affectation logique de coalescence des nuls — un raccourci pour a = a ?? b, avec court-circuit en prime : si a a déjà une valeur, l'opérande de droite n'est même pas évalué. Très pratique pour compléter les valeurs manquantes d'un objet d'options.

Apprendre à coder avec Coddy

COMMENCER