Une façon plus concise d'écrire une fonction
Les fonctions fléchées (arrow functions) offrent une syntaxe plus compacte pour définir une fonction en JavaScript. Apparues avec ES2015, elles sont devenues le style par défaut pour les petites fonctions en ligne, notamment les callbacks passés aux méthodes de tableau, les gestionnaires de promesses et les écouteurs d'événements.
La structure est la suivante : les paramètres, puis =>, puis le corps de la fonction.
Résultat identique à la forme classique :
const add = function (a, b) {
return a + b;
};
Écrire moins de code, c'est sympa, mais les vraies raisons d'adopter les fonctions fléchées, c'est le return implicite et leur gestion particulière de this. On va voir les deux juste après.
Le return implicite en JavaScript
Quand le corps de la fonction se résume à une seule expression, tu peux virer les accolades et le mot-clé return. La valeur de l'expression est renvoyée automatiquement :
C'est précisément là que les fonctions fléchées brillent — une transformation sur une seule ligne se lit comme une formule mathématique :
Dès que tu as besoin de plus d'une instruction, retour aux accolades et au return explicite :
L'erreur la plus classique avec les fonctions fléchées, c'est d'oublier le return à l'intérieur des accolades. Par exemple, x => { x * 2 } renvoie undefined : dès qu'on met des accolades, le corps devient un bloc, et l'expression à l'intérieur est tout simplement ignorée.
Les parenthèses autour des paramètres
Quand il y a un seul paramètre, les parenthèses sont facultatives :
Avec zéro, deux paramètres ou plus, les parenthèses deviennent obligatoires :
Certaines équipes préfèrent toujours mettre les parenthèses par souci de cohérence. Les deux styles se valent — choisis-en un et tiens-t'y.
Renvoyer un objet littéral
Attention, piège classique. Si tu essaies de renvoyer un objet de manière implicite, les accolades sont interprétées comme le corps de la fonction :
Le résultat affiché est undefined. En fait, JavaScript interprète { name: name } comme un bloc contenant une instruction étiquetée, et non comme un littéral d'objet. Pour forcer l'interprétation comme expression, il faut entourer l'objet de parenthèses :
Les parenthèses () autour de { ... }, c'est la solution. Gardez-la en tête — vous tomberez sur ce piège dès la première semaine où vous écrirez des fonctions fléchées.
Le this lexical des fonctions fléchées
La vraie raison d'être des fonctions fléchées, ce n'est pas la syntaxe plus courte. C'est qu'elles n'ont pas leur propre this : elles l'héritent du contexte englobant.
Pour bien comprendre pourquoi c'est important, prenons une fonction classique utilisée comme callback :
À l'intérieur de la function () { ... } passée à setInterval, le this ne correspond pas à counter. Les fonctions classiques ont leur propre this, déterminé par la manière dont on les appelle, et setInterval invoque le callback avec un this qui vaut undefined (en mode strict) ou l'objet global.
Une fonction fléchée, elle, conserve le this de la méthode englobante :
À l'intérieur de la fonction fléchée, this reste counter parce que la flèche n'introduit pas son propre this. Avant l'arrivée des fonctions fléchées, on contournait ce problème avec const self = this; ou .bind(this). Ces astuces fonctionnent toujours, mais on en a rarement besoin aujourd'hui.
Ce que les fonctions fléchées n'ont pas
Ce this lexical fait partie d'un schéma plus large : les fonctions fléchées se passent de plusieurs choses qu'ont les fonctions classiques.
- Pas de
thispropre — il est hérité de la portée englobante. - Pas d'objet
arguments— utilisez plutôt les paramètres rest (...args). - Pas de
new— impossible d'utiliser une fonction fléchée comme constructeur. - Pas de propriété
prototype— conséquence directe de l'absence denew.
...args t'offre la même souplesse que l'ancien arguments pour accepter un nombre quelconque d'arguments, avec le bonus d'être un vrai tableau. Quant à l'appel new Greeter(...), il plante tout simplement parce qu'une fonction fléchée ne peut pas servir de constructeur.
Quand éviter la fonction fléchée
Les fonctions fléchées sont devenues le choix par défaut pour les callbacks, mais il y a quelques situations où elles posent problème :
Les méthodes d'objet définies avec la syntaxe fléchée ne voient pas leur this lié à l'objet : elles l'héritent de l'endroit où le littéral d'objet a été écrit (généralement le module ou la portée globale). Pour les méthodes, utilisez plutôt la syntaxe raccourcie (greet() { ... }).
Même logique pour les méthodes de prototype de classe, les gestionnaires d'événements qui ont besoin que this pointe vers l'élément, et toute fonction que vous comptez appeler avec new. Dans ces cas-là, une vraie function est l'outil adapté.
Une règle simple à retenir
- Callback court, une seule expression ? Fonction fléchée.
- Besoin que
thisreste lié à la portée englobante ? Fonction fléchée. - Définition d'une méthode sur un objet ou un prototype de classe ? Fonction classique (ou méthode raccourcie).
- Écriture d'un constructeur ? Fonction classique, ou mieux encore, une
class.
Dans n'importe quelle vraie base de code JavaScript, vous croiserez les deux styles. Savoir lequel choisir demande quelques semaines à lire du code écrit par d'autres — ensuite, ça devient un réflexe.
La suite : paramètres et valeurs par défaut
Les fonctions fléchées et les fonctions classiques partagent exactement les mêmes fonctionnalités côté paramètres : valeurs par défaut, paramètres du reste, déstructuration des arguments, et plus encore. C'est le sujet de la page suivante, et ça s'applique à toutes les formes de fonctions vues jusqu'ici.
Questions fréquentes
C'est quoi une fonction fléchée en JavaScript ?
Une fonction fléchée, c'est une façon plus concise d'écrire une fonction, avec la syntaxe =>. Par exemple, const add = (a, b) => a + b; prend deux arguments et retourne leur somme. Au-delà de la syntaxe raccourcie, les fonctions fléchées n'ont pas leur propre this, ni leur propre arguments ou super — elles héritent tout ça de la portée englobante.
Quelle différence entre une fonction fléchée et une fonction classique ?
Une fonction déclarée avec function possède son propre this, son propre objet arguments, et peut servir de constructeur avec new. Les fonctions fléchées n'ont rien de tout ça : elles récupèrent le this de l'endroit où elles sont définies. Autre point : elles ne bénéficient pas du hoisting comme les déclarations function.
Quand utiliser une fonction fléchée ?
Les fonctions fléchées sont idéales pour les callbacks courts (arr.map(x => x * 2)), et partout où tu veux que this reste lié à la portée englobante — typiquement dans une méthode de classe qui passe un handler à setTimeout ou à un addEventListener. Pour les méthodes d'objet, les constructeurs et les fonctions autonomes de premier niveau, garde une function classique.