Question 1Si tu déclares const twice = n => n * 2; puis que tu affiches twice(4), qu'est-ce qui s'affiche ?
Fonctions fléchées — formes courtes et renvoi d'objets
Réécrire une fonction avec =>, savoir quand omettre parenthèses et accolades, renvoyer un objet et écrire un corps en bloc.
Même pour un traitement court, comme mettre en forme chaque élément d'un tableau, une expression de fonction t'oblige à écrire à chaque fois function, des accolades et return, et le vrai calcul se perd au milieu de la syntaxe.
Les fonctions fléchées, qui créent des fonctions avec =>, allègent cette écriture ; nous verrons aussi les formes courtes qui se passent des parenthèses et des accolades.
Écrire la même fonction en plus court — la forme de base des fonctions fléchées
Les fonctions qui reçoivent une valeur, font un seul calcul et renvoient le résultat sont courantes : calculer les points de fidélité à partir d'un montant d'achat, par exemple. Pourtant, chacune demande le mot-clé function, des accolades et return ; quand les expressions de fonction s'accumulent, la syntaxe se voit plus que les calculs.
Une fonction fléchée (une façon de créer une fonction avec =>) s'écrit const nom = (paramètres) => { corps };. Tu supprimes le mot-clé function et tu places => entre la liste des paramètres et le corps ; ensuite, tu l'affectes à une variable et tu l'appelles exactement comme une expression de fonction.
// Ce que tu connais déjà : une expression de fonction, qui affecte une fonction à une variable
const rewardPoints = function (price) {
return price * 0.02;
};
// Fonction fléchée
const rewardPointsArrow = (price) => {
return price * 0.02;
};
console.log(rewardPoints(3200)); // 64
console.log(rewardPointsArrow(3200)); // 64
console.log(typeof rewardPointsArrow); // function
Les deux fonctions portent des noms différents uniquement pour pouvoir les comparer. Dans les deux cas, typeof donne function, et elles reçoivent leurs paramètres et utilisent return exactement de la même façon. Quand certaines conditions sont réunies, tu peux raccourcir encore cette forme de base en supprimant les parenthèses ou return.
Supprimer les parenthèses et return — un seul paramètre et return implicite
Certains calculs tiennent en une seule expression : ajouter les frais de port à un montant, vérifier si un total atteint 5000 yens. Avec la forme de base, même un calcul d'une ligne en prend trois une fois les accolades et return ajoutés, et quand ce genre de fonctions s'accumule, accolades et return occupent l'essentiel du code.
S'il y a exactement un paramètre, tu peux supprimer les parenthèses qui l'entourent. Et si le corps est une seule expression, tu peux aussi supprimer les accolades et return. C'est le return implicite (la règle selon laquelle la valeur de l'expression du corps devient directement la valeur de retour) qui rend cela possible.
// Forme de base : parenthèses du paramètre, accolades du corps et return, tout est écrit
const withFee = (price) => {
return price + 500;
};
// Forme courte
const withFeeShort = price => price + 500;
const isFreeShipping = total => total >= 5000;
console.log(withFee(1200)); // 1700
console.log(withFeeShort(1200)); // 1700
console.log(isFreeShipping(4800)); // false
Le corps de isFreeShipping est une seule comparaison : si tu passes 4800, tu récupères directement false, le résultat de 4800 >= 5000. Le return implicite renvoie la valeur de l'expression, quelle qu'elle soit ; un calcul et une comparaison s'écrivent donc exactement de la même façon.
Sans paramètre ou avec plusieurs, les parenthèses sont obligatoires
Si tu retires les parenthèses quand il n'y a aucun paramètre, comme dans () => expression, ou quand il y en a deux ou plus, comme dans (price, rate) => expression, tu obtiens une SyntaxError et le code ne démarre même pas. Si tu ajoutes un paramètre plus tard, pense à remettre les parenthèses. Avec un seul paramètre, tu peux aussi les garder : (price) => expression.
Renvoyer un objet — l'entourer de parenthèses
Quand tu mets en forme un enregistrement pour l'affichage, tu veux souvent renvoyer un objet avec plusieurs clés plutôt qu'un simple nombre. Mais si tu gardes la forme courte et que tu écris les accolades de l'objet juste après =>, tu obtiens undefined au lieu d'un objet.
Les accolades écrites après => sont lues comme un corps en bloc (une zone où tu peux écrire autant d'instructions que tu veux), et non comme un objet. Pour renvoyer un objet, entoure-le de parenthèses, comme dans (name) => ({ name: name }), afin que les accolades soient lues comme une expression.
// Des accolades seules sont lues comme un corps en bloc
const toBadge = (name) => { label: name };
console.log(toBadge("Souris sans fil")); // undefined
// Entourées de parenthèses, les accolades sont lues comme un objet
const toCard = (name, stock) => ({ name: name, inStock: stock > 0 });
const card = toCard("Souris sans fil", 4);
console.log(JSON.stringify(card)); // {"name":"Souris sans fil","inStock":true}
console.log(card.inStock); // true
Avec deux clés ou plus, comme dans { name: name, inStock: true }, le contenu ne peut pas être lu comme des instructions : une SyntaxError empêche le code de démarrer. Avec une seule clé, label: name se trouve être une instruction valide (une étiquette suivie d'une expression) ; il n'y a donc pas d'erreur et tu obtiens undefined sans t'en rendre compte tant que tu n'affiches pas le résultat.
Quand le corps tient sur plusieurs lignes — corps en bloc et return
Certaines fonctions doivent calculer une valeur intermédiaire ou choisir selon une condition avant de décider quoi renvoyer, comme le nombre de jours qui restent au client pour retourner un produit. La forme courte à une seule expression n'a aucun endroit où garder une valeur intermédiaire, ni aucun moyen de renvoyer une valeur différente selon la condition.
Un corps en bloc peut contenir des instructions comme const et if, mais le return implicite ne s'y applique pas : pour renvoyer une valeur, tu écris return. Une fonction peut contenir plusieurs return, et elle se termine sur celui qui s'exécute en premier.
// Corps d'une seule expression : la valeur de l'expression revient telle quelle
const shortMessage = (days) => `${days} jours depuis l'achat`;
console.log(shortMessage(12)); // 12 jours depuis l'achat
// Corps en bloc : calcule des valeurs intermédiaires et fait un return selon la condition
const returnMessage = (days, isOpened) => {
const limit = isOpened ? 7 : 14;
if (days > limit) {
return "Délai de retour dépassé"; // La fonction se termine ici
}
return `Encore ${limit - days} jours`;
};
console.log(returnMessage(12, false)); // Encore 2 jours
console.log(returnMessage(12, true)); // Délai de retour dépassé
// Sans return, tu obtiens undefined
const brokenMessage = (days) => { `Encore ${days} jours`; };
console.log(brokenMessage(12)); // undefined
Si tu écartes d'abord, avec un return, les cas qui ne remplissent pas la condition, les lignes suivantes n'ont plus qu'à traiter le cas normal. Le tableau ci-dessous montre ce que reçoit l'appelant selon la façon d'écrire le corps.
| Écriture du corps | Dans le corps | Valeur reçue par l'appelant |
|---|---|---|
| days => expression | Renvoyée telle quelle | 12 jours depuis l'achat |
| (days, isOpened) => {… return} | Valeur du return | Encore 2 jours / Délai de retour dépassé |
| days => { expression seule } | Non renvoyée | undefined |
this ne fonctionne pas comme dans les fonctions classiques
Dans la méthode d'un objet, tu peux utiliser this (un mot-clé qui désigne l'objet sur lequel la méthode a été appelée). Une fonction fléchée n'a pas son propre this : elle utilise celui du code qui l'entoure. L'article sur les classes, dans le chapitre sur la programmation orientée objet, revient sur cette différence.
Vérification des connaissances
Répondez à chaque question une par une.
Question 2Que renvoie un appel à const toItem = name => { label: name }; ?
Question 3Dans une fonction fléchée à deux paramètres, que se passe-t-il si tu supprimes les parenthèses qui les entourent ?