Expressions de fonctions JavaScript
JavaScript propose plusieurs façons de définir des fonctions, notamment les déclarations de fonctions et les expressions de fonctions.
Introduction aux expressions de fonctions en JavaScript
JavaScript offre plusieurs façons de définir des fonctions, et deux des plus fondamentales sont les déclarations de fonctions et les expressions de fonctions. Une expression de fonction vous permet de traiter une fonction comme n'importe quelle autre valeur : vous pouvez la stocker dans une variable, la passer à une autre fonction ou la retourner depuis une fonction. Comprendre précisément en quoi les expressions diffèrent des déclarations — notamment en ce qui concerne le hoisting — vous évitera toute une catégorie de bugs déroutants.
Cette page couvre la syntaxe des expressions de fonctions, pourquoi elles se comportent différemment des déclarations, les expressions nommées, les utilisations les plus courantes dans la pratique (callbacks, IIFE, gestionnaires d'événements, code asynchrone), et comment tout cela se connecte aux fonctions fléchées modernes.
Expressions de fonctions : syntaxe et utilisation
Qu'est-ce qu'une expression de fonction ?
Une expression de fonction définit une fonction dans le cadre d'une expression plus large — généralement le côté droit d'une affectation. La fonction elle-même n'est qu'une valeur, et la variable à laquelle vous l'assignez devient le moyen de l'appeler. Voici la forme la plus basique :
Comparez cela à une déclaration de fonction, qui commence par le mot-clé function en tant qu'instruction autonome :
Les deux produisent un greet appelable, mais ils sont traités par le moteur à des moments différents — c'est précisément ce dont traite la section suivante.
Hoisting : la différence clé
Les déclarations de fonctions sont hissées (hoisted) : le moteur les lit pendant la phase de compilation, donc la fonction existe avant la ligne où elle est écrite. Vous pouvez l'appeler plus tôt dans le fichier. Les expressions de fonctions ne le sont pas — la valeur de la fonction n'est assignée que lorsque l'exécution atteint cette ligne, donc l'appeler trop tôt échoue :
Remarque : Avec var, le nom greet est hissé mais sa valeur est undefined jusqu'à l'exécution de l'affectation, donc l'appeler trop tôt lève une TypeError (« greet is not a function »). Avec let ou const, le nom se trouve dans la zone morte temporelle et vous obtenez une ReferenceError à la place. Dans tous les cas, la règle est la même : définissez une expression de fonction avant de l'utiliser.
Caractéristiques des expressions de fonctions
- Fonctions anonymes : Les expressions de fonctions sont souvent anonymes — la fonction n'a pas de nom propre et est référencée via la variable.
- Stockées dans des variables : La fonction est une valeur, elle vit donc dans une variable (ou un élément de tableau, une propriété d'object, etc.).
- Citoyens de première classe : En JavaScript, les fonctions sont des valeurs de première classe — elles peuvent être passées comme arguments, retournées par d'autres fonctions, et assignées à des variables.
- Expressions de fonctions nommées : Une expression peut porter son propre nom (ex.
let fn = function myFunc() {}). Le nom n'est visible qu'à l'intérieur de la fonction, ce qui améliore les traces de pile et permet à la fonction de s'appeler elle-même. - Fonctions fléchées : Le code moderne utilise souvent des fonctions fléchées (
() => {}) comme forme abrégée d'expression, bien qu'elles gèrentthisdifféremment.
Expressions de fonctions nommées
Donner un nom interne à une expression permet à la fonction de se référencer elle-même de façon fiable — pratique pour la récursion — même si la variable externe est réassignée ultérieurement :
Applications pratiques des expressions de fonctions
Fonctions de rappel (Callbacks)
L'utilisation la plus courante d'une expression de fonction est en tant que callback — une fonction passée dans une autre fonction et exécutée plus tard, après la fin d'une opération. Passer la fonction en ligne en tant qu'expression maintient la logique exactement là où elle est utilisée :
IIFE (Expression de fonction immédiatement invoquée)
Une IIFE est une expression de fonction qui s'exécute au moment où elle est définie. Les parenthèses enveloppantes transforment la fonction en expression, et le () final l'appelle immédiatement. C'était la façon classique de créer une portée privée et d'éviter de laisser fuiter des variables dans la portée globale :
Remarque : Aujourd'hui, let/const à portée de bloc et les modules ES couvrent la plupart des cas d'usage des IIFE, donc vous les verrez moins dans le nouveau code — mais elles restent courantes dans les anciennes bibliothèques et les scripts groupés.
Expressions de fonctions vs déclarations de fonctions
| Déclaration de fonction | Expression de fonction | |
|---|---|---|
| Syntaxe | function f() {} en tant qu'instruction | let f = function () {} dans une expression |
| Hoisting | Entièrement hissée — appelable avant sa ligne | Non appelable avant l'exécution de l'affectation |
| Nom | Toujours nommée | Souvent anonyme (peut être nommée) |
| Idéale pour | Fonctions utilitaires de haut niveau utilisées dans tout un fichier | Callbacks, IIFE, définitions conditionnelles |
Une règle pratique : optez pour une déclaration pour une fonction autonome et réutilisable, et pour une expression lorsque la fonction est une valeur que vous allez passer quelque part ou définir conditionnellement.
Exemples avancés et cas d'utilisation
Gestion des événements
Dans le navigateur, les expressions de fonctions sont le moyen naturel d'attacher des gestionnaires d'événements, puisque vous passez la fonction directement à addEventListener :
document.getElementById('myButton').addEventListener('click', function () {
console.log('Button clicked!');
});Programmation asynchrone
Avec les Promises et async/await, les expressions de fonctions offrent un moyen concis de faire circuler des unités de code. Ici, une expression de fonction traite chaque valeur résolue :
Conclusion
Maîtriser les expressions de fonctions en JavaScript est essentiel pour écrire un code efficace et maintenable. Leur flexibilité, associée à la puissance des capacités de programmation fonctionnelle de JavaScript, en fait un outil indispensable dans l'arsenal d'un développeur.
N'oubliez pas que le choix entre une expression de fonction et une déclaration de fonction dépend des exigences spécifiques de votre code et du contexte dans lequel vous travaillez. Continuez à pratiquer et à explorer ces concepts pour approfondir votre compréhension et votre maîtrise de JavaScript.