Apprenez en lisant dans l'ordre

Paramètres par défaut et du reste — valeurs de repli et arguments restants

Paramètres par défaut, paramètres du reste qui regroupent les arguments dans un tableau, et objet options.

Certains arguments reçoivent presque toujours la même valeur, comme des frais de port ou un taux de TVA. Si tu en oublies un, aucune erreur ne s'affiche : tu ne t'en aperçois que lorsque undefined apparaît dans le texte affiché.

Cet article présente les paramètres par défaut, qui fixent la valeur utilisée quand un argument est omis, les paramètres du reste, qui regroupent un nombre quelconque d'arguments, et le motif options, qui transmet des réglages dans un seul objet.

Rendre un argument facultatif — les paramètres par défaut

Imagine une fonction qui prépare la réservation d'une salle de réunion : la durée est presque toujours d'une heure, et la disposition presque toujours en classe. Si tu dois quand même écrire les trois arguments à chaque appel, la seule valeur que tu veux vraiment changer se perd dans l'appel.

Un paramètre par défaut (une façon de fixer à l'avance la valeur à utiliser quand un argument n'est pas transmis) s'écrit en ajoutant = dans la liste des paramètres, comme dans hours = 1. Un paramètre qui a une valeur par défaut peut être omis à l'appel.

// La valeur par défaut s'écrit en ajoutant « = valeur » dans la liste des paramètres
const reserveRoom = (roomName, hours = 1, layout = "classe") => {
  return `${roomName} / ${hours} h / ${layout}`;
};

// Si tu omets le 3e, la valeur par défaut "classe" est utilisée
console.log(reserveRoom("Salle A", 2));           // Salle A / 2 h / classe

// Là où tu passes une valeur, la valeur par défaut n'est pas utilisée
console.log(reserveRoom("Salle A", 2, "en U"));   // Salle A / 2 h / en U

// Si tu omets aussi le 2e, les deux valeurs par défaut sont utilisées
console.log(reserveRoom("Salle A"));              // Salle A / 1 h / classe
Les arguments se remplissent à partir de la gauche
Salle A passéà roomNamePas de valeurpar défautroomName vautSalle A2 passéà hoursLe 1 par défautn'est pas utiliséhours vaut 2Rien de passépour layoutLa valeur pardéfaut s'appliquelayout vautclasse
On suit reserveRoom("Salle A", 2) position par position. Même avec une valeur par défaut, rien ne change si une valeur est transmise.

Tu ne peux omettre des arguments qu'en partant de la droite : place donc les paramètres qui ont une valeur par défaut en dernier. Même si tu veux seulement changer le 3e argument, tu dois écrire une valeur en 2e position.

Tu vas estimer des frais de port. boxCount et les tarifs par colis de chaque région sont déjà déclarés ; les frais de port valent le tarif par colis × le nombre de colis.

① Écris une fonction qui reçoit un nombre de colis et une région, et renvoie les frais de port, avec 1 colis et Honshu (l'île principale du Japon) comme valeurs par défaut.

② Sans préciser la région, affiche les frais de port pour boxCount colis sous la forme « Honshu : X yens ».

③ Indique Hokkaido comme région et affiche « Hokkaido : X yens ».

④ Sans passer aucun argument, affiche « Par défaut : X yens ».

(Si le code s'exécute correctement, une explication s'affiche.)

Éditeur JavaScript / TypeScript

Exécuter le code pour voir le résultat

Ce que reçoit un argument non transmis — undefined et valeurs par défaut

Si tu omets l'argument d'un paramètre sans valeur par défaut, le code qui l'utilise dans un calcul ou une chaîne s'exécute quand même. Comme rien ne s'arrête, tu te retrouves ensuite à chercher quel appel a oublié de le transmettre.

Un paramètre qui ne reçoit pas d'argument vaut undefined. La valeur par défaut n'est utilisée que si l'argument vaut undefined : si tu passes null, 0 ou une chaîne vide, c'est la valeur transmise qui est utilisée.

const notifyStatus = (orderId, status = "Reçue") => `${orderId}: ${status}`;

// Omettre l'argument ou passer undefined donne la valeur par défaut dans les deux cas
console.log(notifyStatus("A-1021"));             // A-1021: Reçue
console.log(notifyStatus("A-1021", undefined));  // A-1021: Reçue

// null compte comme une valeur transmise : la valeur par défaut n'est pas utilisée
console.log(notifyStatus("A-1021", null));       // A-1021: null

// Un paramètre omis sans valeur par défaut reçoit undefined
const plainStatus = (orderId, status) => `${orderId}: ${status}`;
console.log(plainStatus("A-1021"));              // A-1021: undefined
Omettre l'argument ou passer null
Appel sansstatusstatus vautundefined= "Reçue"s'appliqueA-1021:Reçuenull passéà statusstatus vautnullLa valeur pardéfaut nes'applique pasA-1021:null
Un status omis reçoit undefined, donc l'expression par défaut s'exécute. null est traité comme une valeur transmise : la valeur par défaut ne s'applique pas.

Le tableau ci-dessous montre, pour chaque deuxième argument passé à notifyStatus, la valeur que reçoit status et ce qui s'affiche. Passer undefined donne le même résultat qu'omettre l'argument, alors que null s'affiche tel quel, exactement comme une chaîne transmise.

AppelValeur de statusAffichage
notifyStatus("A-1021")La valeur par défaut, ReçueA-1021: Reçue
notifyStatus("A-1021", "Expédiée")ExpédiéeA-1021: Expédiée
notifyStatus("A-1021", undefined)La valeur par défaut, ReçueA-1021: Reçue
notifyStatus("A-1021", null)nullA-1021: null

Si tu passes null, la valeur par défaut est ignorée

null est une valeur qui signifie « vide volontairement » : une valeur par défaut dans la liste des paramètres ne la remplace pas. Si tu veux la valeur de repli même quand la réponse d'une API contient null, ne mets pas de valeur par défaut sur le paramètre et utilise plutôt ?? dans la fonction, comme dans const shown = status ?? "Reçue";.

Tu vas afficher des niveaux de stock. products est déjà déclaré ; il contient un produit avec un stock de 0, un sans clé stock et un avec null.

① Écris stockLabel, qui reçoit un stock et renvoie « (stock : X) », avec « à vérifier » comme valeur par défaut.

② Affiche chaque produit sous la forme « [nom du produit] (stock : X) ».

③ Écris stockLabelSafe, qui transforme aussi null en « à vérifier », sans utiliser de valeur par défaut.

④ Affiche de nouveau le Câble et le Hub USB, cette fois avec stockLabelSafe.

Éditeur JavaScript / TypeScript

Exécuter le code pour voir le résultat

Regrouper un nombre variable d'arguments — les paramètres du reste

Certaines fonctions reçoivent un nombre de valeurs différent à chaque appel, comme les étiquettes d'un produit ou les lignes d'une note de frais. Même si tu déclares cinq paramètres, un appel finira par en demander un sixième, et ceux qui ne servent pas valent undefined à chaque fois.

Un paramètre du reste (une façon de recevoir les arguments restants regroupés dans un seul tableau ; c'est ce qui permet d'écrire des fonctions variadiques) s'écrit ...labels à la fin de la liste des paramètres. C'est le même ... qui regroupait les éléments restants lors de la déstructuration, sauf qu'ici il regroupe des arguments. Il ne peut être que le dernier paramètre : en placer un autre après lui provoque une SyntaxError.

// Écrire ...labels regroupe les arguments reçus dans un seul tableau
const buildTags = (...labels) => `Tags (${labels.length}) : ${labels.join(" / ")}`;

console.log(buildTags("Livraison gratuite", "En stock"));  // Tags (2) : Livraison gratuite / En stock
console.log(buildTags("Nouveau"));                         // Tags (1) : Nouveau

// Dans l'autre sens, ... entre les parenthèses de l'appel transforme un tableau en arguments
console.log(buildTags(...["Nouveau", "Limité"]));          // Tags (2) : Nouveau / Limité

// S'il y a aussi des paramètres nommés, place le paramètre du reste en dernier
const buildNotice = (orderId, ...notes) => `${orderId} (${notes.join(", ")})`;

console.log(buildNotice("A-1021", "Réfrigéré", "Créneau horaire"));  // A-1021 (Réfrigéré, Créneau horaire)
console.log(buildNotice("A-1022"));                                  // A-1022 ()
Dans quel paramètre va chaque valeur
1re valeur"A-1021"Va dansorderId2e valeur"Réfrigéré"Va dansnotes[0]3e valeur"Créneau horaire"Va dansnotes[1]
La première valeur va dans orderId, et les suivantes vont, dans l'ordre, dans les éléments de notes. Un paramètre du reste reçoit tout ce qui reste après les paramètres nommés.

Un paramètre du reste ne peut pas avoir de valeur par défaut, mais quand aucun argument ne lui revient, notes est un tableau vide, et non undefined. Dans l'autre sens, si tu as un tableau et que tu veux passer ses éléments comme arguments séparés, écris ... entre les parenthèses de l'appel.

Tu vas additionner les frais de transport d'un déplacement professionnel. trainFare, busFare et taxiFare sont déjà déclarées.

① Écris sumExpenses avec un paramètre du reste : elle additionne tous les montants reçus et renvoie le total.

② Affiche le total des 3 trajets sous la forme « Total en yens : X ».

③ Affiche, sous la même forme, le résultat d'un appel sans aucun argument.

④ Écris summarize, qui reçoit un nom de catégorie suivi d'un nombre quelconque de montants, puis passe-lui « Transport » et les 3 trajets, et affiche « Transport : X yens (N dépenses) ».

Éditeur JavaScript / TypeScript

Exécuter le code pour voir le résultat

Transmettre des réglages par leur nom — objet options et déstructuration

Quand les réglages s'accumulent, comme pour l'envoi d'un e-mail, tu te retrouves avec des appels comme sendMail(to, subject, false, true). Impossible de savoir ce que signifient ce false et ce true sans ouvrir la définition de la fonction.

Avec le motif options (une façon de transmettre plusieurs réglages regroupés dans un seul objet), la fonction qui reçoit l'objet le déstructure et donne une valeur par défaut à chaque clé. Pour gérer les appels qui ne passent aucun réglage, ajoute = {} après le motif de déstructuration : un objet vide est alors utilisé quand aucun objet n'est transmis.

// Plus il y a de paramètres, plus il est difficile de savoir ce que transmet un appel
const sendMailOld = (to, subject, isUrgent, withPdf) =>
  `${to} / ${subject} / ${isUrgent} / ${withPdf}`;

console.log(sendMailOld("alice@example.com", "Avis d'expédition", false, true));
// alice@example.com / Avis d'expédition / false / true

// Motif options : regroupe les réglages dans un objet et déstructure-le du côté qui le reçoit
const sendMail = (to, { subject = "Information", isUrgent = false } = {}) =>
  `${to} / ${subject} / ${isUrgent}`;

console.log(sendMail("alice@example.com", { isUrgent: true }));  // alice@example.com / Information / true
console.log(sendMail("alice@example.com"));                     // alice@example.com / Information / false
Seules les clés écrites sont remplacées
Passer{ isUrgent: true }true arrivedans isUrgentisUrgent vauttruePas de subjectdans cet appelValeur par défautde subjectsubject vautInformationAutre appel,sans 2e argument= {} fournitdes réglages videsLes deux valeurspar défaut
Seules les clés que tu écris sont transmises ; celles que tu omets gardent leur valeur par défaut. Le = {} final gère les appels qui omettent l'objet entier.

Au lieu de dépendre de l'ordre des paramètres, chaque valeur est identifiée par sa clé : les appels restent lisibles même quand les réglages se multiplient. Les clés correspondent par leur nom, donc même si tu les écris dans un autre ordre, comme dans { isUrgent: true, subject: "Renvoi" }, les valeurs reçues sont les mêmes.

Sans = {}, tu obtiens une TypeError

Si tu écris seulement le motif de déstructuration, comme dans { subject = "Information" }, un appel qui omet le deuxième argument lève TypeError: Cannot read properties of undefined (reading 'subject'). La raison : il essaie de lire une clé dans undefined, la valeur que contient le paramètre omis.

Tu vas changer l'affichage du prix d'un bento (repas en boîte) grâce à un objet de réglages. lunchPrice est déjà déclarée.

① Écris formatPrice, qui reçoit un prix hors taxes et un objet de réglages, et renvoie une chaîne comme « 1058 yens ». Déstructure les réglages, avec un taux de TVA de 0,08 et l'unité « yens » comme valeurs par défaut.

② Affiche le résultat d'un appel sans réglages.

③ Affiche le résultat avec un taux de 0,1 et l'unité « yens (sur place) ».

④ Affiche le résultat avec un taux de 0.

Éditeur JavaScript / TypeScript

Exécuter le code pour voir le résultat
QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1Avec const addFee = (price, fee = 500) => price + fee;, que renvoie addFee(1000, undefined) ?

Question 2Que renvoie const countNotes = (id, ...notes) => notes.length; quand on l'appelle avec countNotes("A-1021") ?

Question 3Que renvoie const send = (to, { urgent = false } = {}) => urgent; quand on l'appelle avec send("alice@example.com") ?