HOWTO · JavaScript

Passer la fonction JavaScript en tant que paramètre

En JavaScript, on peut transmettre une fonction à une autre en lui fournissant sa référence, par exemple `greet`, sans l’appeler. Écrire `greet()` l’exécute immédiatement et transmet à la place la valeur qu’elle renvoie.

Sur cette page

Pour transmettre une fonction en JavaScript, passez sa référence à la fonction qui la reçoit, par exemple greet, sans l’appeler. Écrire greet() l’exécute immédiatement et transmet sa valeur de retour à la place. La fonction qui reçoit cette référence décide si elle appelle la fonction fournie et à quel moment ; celle-ci est souvent appelée fonction de rappel. Cette distinction permet de fournir un comportement qu’une autre fonction pourra utiliser.

Transmettre une fonction nommée comme argument

Une fonction nommée est utile lorsque vous souhaitez décrire une opération séparément ou la réutiliser. Dans cet exemple, formatGreeting reçoit la fonction greet et un nom. Elle appelle la fonction fournie en lui transmettant ce nom :

function greet(name) {
  return "Hello, " + name + "!";
}

function formatGreeting(callback, name) {
  return callback(name);
}

const message = formatGreeting(greet, "Mina");
console.log(message);

L’appel formatGreeting(greet, "Mina") transmet deux valeurs : la référence de fonction greet et la chaîne "Mina". Dans la fonction qui reçoit ces valeurs, callback(name) appelle greet et renvoie son résultat. Si vous écriviez formatGreeting(greet("Mina"), "Mina"), JavaScript appellerait greet avant même que formatGreeting ne commence ; le premier argument serait donc une chaîne, et non une fonction.

Transmettre une fonction avec d’autres arguments

Une fonction peut recevoir plusieurs fonctions de rappel en même temps que des valeurs ordinaires. La fonction qui les reçoit peut choisir quelle fonction appeler et quelle valeur lui transmettre. Ici, applyOperation reçoit un nombre et deux fonctions ; elle applique chacune d’elles à ce nombre :

function applyOperation(value, first, second) {
  return [first(value), second(value)];
}

function double(number) {
  return number * 2;
}

function addThree(number) {
  return number + 3;
}

const results = applyOperation(4, double, addThree);
console.log(results.join(", "));

L’ordre des arguments compte, car les paramètres de applyOperation reçoivent les valeurs dans le même ordre que lors de l’appel. value reçoit 4, first reçoit double et second reçoit addThree. La fonction renvoie un tableau contenant les deux valeurs calculées. Le même principe s’applique lorsqu’une API attend une fonction de rappel accompagnée d’options ou de données : vérifiez l’ordre des paramètres, puis passez chaque fonction par son nom, sans l’appeler.

Utiliser des fonctions anonymes et fléchées comme fonctions de rappel

Lorsqu’une opération n’est nécessaire qu’au moment de l’appel, vous pouvez la définir à cet endroit au lieu de déclarer une fonction nommée. L’exemple suivant passe une fonction anonyme à map, puis une fonction fléchée lors d’un second appel à map :

const numbers = [1, 2, 3];

const doubled = numbers.map(function (number) {
  return number * 2;
});
const tripled = numbers.map((number) => number * 3);

console.log(doubled.join(", "));
console.log(tripled.join(", "));
2, 4, 6
3, 6, 9

map appelle sa fonction de rappel pour chaque élément du tableau et crée un nouveau tableau à partir des valeurs renvoyées ; cette fonction n’a pas besoin d’être nommée. La fonction anonyme utilise le mot-clé function, tandis que la fonction fléchée utilise => et un corps constitué d’une expression dont la valeur est renvoyée implicitement. Choisissez la forme qui rend l’opération claire. Les fonctions fléchées utilisent aussi la valeur lexicale de this héritée du contexte environnant. Si une fonction de rappel a besoin de sa propre valeur this, utilisez une fonction classique et consultez la documentation de l’API appelée pour connaître son comportement concernant this.

Renvoyer une fonction depuis une autre fonction

Une fonction peut aussi en renvoyer une autre. C’est différent du fait de passer une fonction de rappel comme argument : l’appel externe crée et renvoie une fonction que vous pouvez enregistrer et appeler plus tard. Par exemple, makeMultiplier renvoie une fonction qui conserve le multiplicateur choisi dans sa portée environnante :

function makeMultiplier(multiplier) {
  return function (number) {
    return number * multiplier;
  };
}

const triple = makeMultiplier(3);
console.log(triple(5));

makeMultiplier(3) renvoie une fonction ; triple désigne donc cette fonction renvoyée. L’appel triple(5) lui transmet ensuite son argument number. La fonction interne peut toujours lire multiplier, défini lors de l’appel qui l’a créée : cet accès conservé s’appelle une fermeture (closure). Une fonction d’ordre supérieur est une fonction qui accepte une autre fonction, en renvoie une, ou fait les deux.

Questions fréquentes

Comment passer plusieurs fonctions ? Placez chaque référence de fonction à sa propre position d’argument, en les séparant par des virgules, et faites correspondre leur ordre à celui des paramètres de la fonction qui les reçoit.

Quand une fonction de rappel est-elle exécutée ? C’est la fonction qui la reçoit qui décide quand l’appeler. Passer une fonction ne l’appelle pas ; selon sa conception, la fonction réceptrice peut l’appeler immédiatement, plus tard ou plusieurs fois.

Une fonction peut-elle en renvoyer une autre ? Oui. Appelez la fonction externe pour obtenir la fonction renvoyée, puis appelez ou transmettez cette dernière selon vos besoins. Cette technique sert souvent à créer des fonctions dont la configuration est conservée dans une fermeture.