Mini-JS b_higher-order
Fonctions d’ordre supérieur
En JavaScript, les fonctions ne sont pas seulement des blocs de code que l’on exécute : ce sont aussi des valeurs à part entière. Cela signifie qu’elles peuvent être stockées dans des variables, transmises en argument ou même renvoyées en résultat. On appelle fonctions d’ordre supérieur celles qui manipulent d’autres fonctions.
Concrètement, une fonction d’ordre supérieur peut recevoir une fonction en paramètre, l’appliquer à une série de données, ou bien produire une nouvelle fonction adaptée à un besoin particulier. Ces mécanismes, que l’on retrouve dans d’autres langages comme Python ou Lisp, ouvrent la porte à une programmation plus expressive et modulaire.
Exemple avec map
Commençons avec un exemple classique. Définissons deux fonctions simples :
let add_2 = function (x) {
return x + 2;
};
let double = function (x) {
return 2 * x;
};Créons maintenant une fonction d’ordre supérieur appelée
map. Celle-ci prend deux arguments : une fonction
func et un tableau list. Elle applique
func à chaque élément du tableau et renvoie le
tableau transformé :
let map = function (func, list) {
let output = [];
for (let idx in list) {
output.push(func(list[idx]));
}
return output;
};
map(add_2, [5, 6, 7]); // => [7, 8, 9]
map(double, [5, 6, 7]); // => [10, 12, 14]Ici, map agit comme un intermédiaire : elle ne
connaît pas à l’avance la transformation à effectuer, mais elle
délègue cette responsabilité à la fonction reçue en argument.
Générer des fonctions spécialisées
Puisque nous appelons souvent map(add_2, ...) ou
map(double, ...), il peut être utile de créer des
fonctions spécialisées. On peut le faire en composant des
fonctions :
let process_add_2 = function (list) {
return map(add_2, list);
};
let process_double = function (list) {
return map(double, list);
};
process_add_2([5, 6, 7]); // => [7, 8, 9]
process_double([5, 6, 7]); // => [10, 12, 14]Pour éviter de dupliquer ce schéma, écrivons une fonction d’ordre supérieur qui fabrique automatiquement ce genre de processeur :
let buildProcessor = function (func) {
return function (list) {
return map(func, list);
};
};
let process_add_2 = buildProcessor(add_2);
let process_double = buildProcessor(double);
process_add_2([5, 6, 7]); // => [7, 8, 9]
process_double([5, 6, 7]); // => [10, 12, 14]Ainsi, avec une seule fonction générique
(buildProcessor), nous générons des fonctions
spécialisées adaptées à chaque transformation.
Créer des fonctions sur mesure
Les fonctions d’ordre supérieur permettent aussi de construire des générateurs de fonctions. Prenons l’exemple d’un multiplicateur :
let buildMultiplier = function (x) {
return function (y) {
return x * y;
};
};
let double = buildMultiplier(2);
let triple = buildMultiplier(3);
double(3); // => 6
triple(3); // => 9Ici, buildMultiplier fabrique de nouvelles
fonctions capables de multiplier n’importe quel nombre par une
valeur donnée. L’intérêt est clair : on crée à la volée des outils
adaptés à un usage spécifique.
À retenir
Les fonctions d’ordre supérieur illustrent la puissance de JavaScript en tant que langage fonctionnel. Elles rendent possible la composition, la création de fonctions spécialisées, et une écriture plus concise et expressive. Grâce à elles, le code devient à la fois plus flexible et plus réutilisable.