Menu
Français

Optional Chaining (?.) en JavaScript : accès sécurisé

Comment l'opérateur ?. permet de parcourir des objets imbriqués, des tableaux et des méthodes sans planter sur un null ou un undefined.

Le problème : l'accès aux propriétés imbriquées est fragile

Aller chercher une valeur au fond d'un objet imbriqué, ça fonctionne très bien… jusqu'au jour où l'un des niveaux n'existe pas :

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

user.address vaut undefined, et tenter de lire .city sur undefined déclenche une TypeError: Cannot read properties of undefined. Dans la vraie vie, les données qu'on manipule — réponses d'API, JSON parsé, requêtes DOM — regorgent de champs qui peuvent être présents ou non, et multiplier les vérifications à chaque niveau devient vite pénible :

const city = user && user.address && user.address.city;

Ça passe encore avec deux niveaux. À quatre, c'est l'enfer. L'opérateur ?. est une solution bien plus propre.

L'opérateur ?. court-circuite sur null et undefined

L'optional chaining en JavaScript ne lit une propriété que si la valeur qui précède n'est pas null ou undefined. Sinon, toute l'expression renvoie undefined et s'arrête là.

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

La première ligne lit name sans souci. La deuxième tombe sur user.address, voit undefined et abandonne — le reste de la chaîne ne s'exécute jamais. La troisième lèverait une erreur sans ?. parce qu'on appellerait .toUpperCase() sur undefined ; avec ?., toute l'expression renvoie tranquillement undefined.

Le modèle mental à retenir : ?. veut dire « si ce qui me précède vaut null ou undefined, laisse tomber et renvoie undefined — sinon, continue ».

Ça marche aussi sur les tableaux et les appels de fonction

Trois syntaxes, une seule et même idée :

index.js
Output
Click Run to see the output here.
  • ?.[...] pour accéder à un élément de tableau ou à une propriété dynamique.
  • ?.() pour appeler quelque chose qui n'est pas forcément une fonction.
  • ?.name pour un accès classique à une propriété.

Les trois se court-circuitent de la même façon. user?.notAMethod?.() ne lève aucune erreur, même si notAMethod n'existe pas : le second ?. tombe sur undefined et s'arrête là.

C'est particulièrement pratique pour les callbacks optionnels :

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

Plus besoin de bricoler un if (typeof onDone === "function") avant chaque appel.

Seuls null et undefined déclenchent le court-circuit

C'est LE détail qui piège tout le monde. L'opérateur ?. ne réagit qu'aux valeurs nullish. Les autres valeurs falsy — 0, "", false, NaN — restent des objets tout à fait valables sur lesquels on peut chaîner (enfin, dans la mesure où l'autoboxing le permet) :

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

data.count vaut 0 : c'est falsy, mais pas nullish. Du coup, ?.toFixed(2) s'exécute bien dessus et renvoie "0.00". À comparer avec && :

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

La version avec && renvoie 0 parce que data.count est falsy et déclenche le court-circuit. La version avec ?. renvoie "0.00", parce que 0 n'est pas nullish. Si tu veux vraiment t'arrêter sur 0, && est le bon choix. Si tu veux t'arrêter uniquement quand « la valeur est absente », alors c'est ?. qu'il te faut.

La position du ? a son importance

?. protège la valeur qui le précède, pas celle qui le suit. Place-le donc sur le niveau susceptible d'être absent :

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

Les trois fonctionnent ici parce qu'en réalité rien ne manque. Mais si config.server peut valoir undefined, il faut écrire config.server?.host — mettre un ?. avant server ne servirait à rien, puisque le vrai problème, c'est de lire .host sur un server absent.

Une bonne règle : placez ?. à chaque niveau où la valeur située avant le point peut réellement être null ou undefined. Saupoudrer des ?. à tous les points « au cas où » masque les bugs et alourdit inutilement le code.

L'affectation via ?. ne fonctionne pas

L'optional chaining est en lecture seule. Impossible de l'utiliser à gauche d'une affectation :

user?.address?.city = "Paris";   // SyntaxError

Ça se tient quand on y réfléchit : qu'est-ce que ça voudrait dire, affecter une valeur à une propriété de undefined ? Si tu veux définir une valeur uniquement quand le parent existe, écris-le explicitement :

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

Quand l'utiliser — et quand s'en passer

L'opérateur ?. en JavaScript brille quand une valeur est légitimement optionnelle :

  • Réponses d'API où certains champs peuvent être absents.
  • Accès au DOM : document.querySelector(".banner")?.remove().
  • Callbacks qui ne sont pas forcément passés : options.onError?.(err).
  • Chaînes d'appels de bibliothèques où un résultat intermédiaire peut valoir null.

En revanche, ce n'est pas le bon outil quand la valeur est censée toujours être présente. Parsemer son code de ?. juste pour faire taire des erreurs, c'est transformer un bug bruyant et facile à repérer (« TypeError à la ligne 42 ») en un bug silencieux (une variable mystérieusement undefined trois fonctions plus loin). Si quelque chose doit exister, laissez le code planter — la stack trace vous rend service.

Un exemple concret

Récupérer une valeur dans une réponse d'API potentiellement incomplète :

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

Chaque ?. gère un niveau d'incertitude. avatarUrl se retrouve à undefined, proprement. onClick?.() appelle le handler seulement s'il est bien là.

Tu remarqueras le ?? sur la ligne de displayName — c'est l'autre moitié du pattern. ?. te renvoie undefined quand quelque chose manque ; ?? te permet de poser une valeur par défaut sans te faire avoir par des valeurs falsy légitimes comme 0 ou "".

La suite : le nullish coalescing

?. et ??, c'est la même idée appliquée à deux problèmes différents : tous les deux traitent null et undefined comme « absent », sans toucher aux autres valeurs falsy. Au programme ensuite : comment ?? permet de définir des valeurs par défaut qui ont du sens — et pourquoi || se plante discrètement là-dessus depuis des années.

Questions fréquentes

À quoi sert ?. en JavaScript ?

L'opérateur ?. accède à une propriété, un index de tableau ou une méthode uniquement si la valeur à gauche n'est ni null ni undefined. Sinon, toute l'expression court-circuite et renvoie undefined au lieu de déclencher une erreur. Typiquement, user?.address?.city ne plantera pas si user ou address est absent.

Quand utiliser l'optional chaining en JavaScript ?

Utilise ?. quand une valeur a légitimement le droit d'être absente : réponses d'API avec des champs optionnels, sélecteurs du DOM qui peuvent ne rien trouver, callbacks passés ou non. Évite de t'en servir pour masquer un bug là où la valeur devrait toujours exister — dans ce cas, une valeur manquante est une vraie info que tu veux voir remonter.

Quelle est la différence entre ?. et && ?

Dans la plupart des cas le résultat est identique, mais ?. court-circuite uniquement sur null ou undefined, alors que && court-circuite sur toute valeur falsy — y compris 0, '' ou false. Par exemple, obj && obj.count renvoie 0 quand count vaut 0 ; obj?.count renvoie 0 lui aussi, mais la chaîne ne s'arrête proprement que sur des valeurs nullish.

Peut-on utiliser l'optional chaining avec les tableaux et les appels de fonction ?

Oui. arr?.[0] lit un index de tableau en toute sécurité, et fn?.() n'appelle la fonction que si elle existe. Même règle dans les deux cas : si la valeur avant ?. est null ou undefined, l'expression vaut undefined et rien d'autre ne s'exécute.

Apprendre à coder avec Coddy

COMMENCER