Si vous apprenez JavaScript, alors vous devez être tombé sur le concept d'une «fonction d'ordre supérieur». Cela peut sembler très compliqué, mais ce n'est pas le cas.
JavaScript convient à la programmation fonctionnelle car il prend en charge le concept de fonctions d'ordre supérieur. De telles fonctions sont largement utilisées dans le langage, et si vous avez programmé en JS, vous avez probablement déjà travaillé avec elles sans même le savoir.

Afin de bien comprendre ce concept, vous devez d'abord comprendre le concept de programmation fonctionnelle (programmation fonctionnelle) et quelles fonctions sont de première classe (fonctions de première classe).
Le matériel, dont nous publions la traduction, est destiné aux débutants, il vise à expliquer le concept de fonctions d'ordre supérieur et à montrer comment les utiliser en JavaScript.
Qu'est-ce que la programmation fonctionnelle?
Si vous décrivez le concept de programmation fonctionnelle en termes simples, il s'avère que c'est une approche de programmation, à l'aide de laquelle vous pouvez passer des fonctions à d'autres fonctions en tant que paramètres et utiliser des fonctions en tant que valeurs renvoyées par d'autres fonctions. Engagés dans la programmation fonctionnelle, nous concevons l'architecture de l'application et écrivons du code à l'aide de fonctions.
Parmi les langages qui prennent en charge la programmation fonctionnelle, on trouve JavaScript, Haskell, Clojure, Scala et Erlang.
Fonctions de première classe
Si vous apprenez JavaScript, vous pourriez entendre que dans un langage, les fonctions sont traitées comme des objets de première classe. En effet, en JavaScript, comme dans d'autres langages qui prennent en charge la programmation fonctionnelle, les fonctions sont des objets.
En particulier, dans JS, les fonctions sont représentées comme des objets d'un type spécial - ce sont des objets de type
Function
. Prenons un exemple:
function greeting() { console.log('Hello World'); } // greeting(); // 'Hello World'
Afin de prouver que les fonctions en JavaScript sont des objets, nous pouvons procéder comme suit, en continuant l'exemple précédent:
// , greeting.lang = 'English'; // 'English' console.log(greeting.lang);
Veuillez noter que l'ajout de vos propres propriétés à des objets standard en JavaScript ne provoque pas de messages d'erreur, ce n'est pas recommandé. Vous ne devez pas ajouter vos propres propriétés aux fonctions. Si vous avez besoin de stocker quelque chose dans un objet, il est préférable de créer un objet spécial pour cela.
En JavaScript avec des fonctions, vous pouvez faire la même chose que vous pouvez faire avec des entités d'autres types, telles que
Object
,
String
,
Number
. Les fonctions peuvent être transmises en tant que paramètres à d'autres fonctions. Ces fonctions, transférées à d'autres, agissent généralement comme des fonctions de rappel (rappels). Des fonctions peuvent être affectées à des variables, stockées dans des tableaux, etc. C'est pourquoi les fonctions dans JS sont des objets de première classe.
Affectation de fonctions aux variables et constantes
Des fonctions peuvent être attribuées à des variables et des constantes:
const square = function(x) { return x * x; }
Les fonctions affectées à des variables ou constantes peuvent être affectées à d'autres variables ou constantes:
const foo = square;
Passer des fonctions comme paramètres
Les fonctions peuvent être passées comme paramètres pour d'autres fonctions:
function formalGreeting() { console.log("How are you?"); } function casualGreeting() { console.log("What's up?"); } function greet(type, greetFormal, greetCasual) { if(type === 'formal') { greetFormal(); } else if(type === 'casual') { greetCasual(); } } // 'What's up?' greet('casual', formalGreeting, casualGreeting);
Maintenant que nous savons comment les fonctions de première classe se comportent, parlons des fonctions d'ordre supérieur.
Fonctions d'ordre supérieur
Les fonctions d'ordre supérieur sont des fonctions qui fonctionnent avec d'autres fonctions, soit en les prenant comme paramètres, soit en les renvoyant. Autrement dit, une fonction d'ordre supérieur est une fonction qui prend une fonction comme argument ou renvoie une fonction comme valeur de sortie.
Par exemple, les fonctions JavaScript intégrées
Array.prototype.map
,
Array.prototype.filter
et
Array.prototype.reduce
sont des fonctions d'ordre supérieur.
Fonctions d'ordre supérieur en action
Considérez des exemples d'utilisation de fonctions d'ordre supérieur intégrées à JS et comparez cette approche avec des actions similaires sans utiliser de telles fonctions.
▍ Méthode Array.prototype.map
La méthode
map()
crée un nouveau tableau, appelant, pour traiter chaque élément du tableau d'entrée, le rappel lui est passé en argument. Cette méthode prend chaque valeur renvoyée par le rappel et la place dans le tableau de sortie.
La fonction de rappel passée à
map()
prend trois arguments:
element
(élément),
index
(index) et
array
(tableau). Regardons quelques exemples.
Exemple n ° 1
Supposons que nous ayons un tableau de nombres et que nous voulons créer un nouveau tableau contenant les résultats de la multiplication de ces nombres par 2. Envisagez des moyens de résoudre ce problème en utilisant et sans fonctions d'ordre supérieur.
Résolution d'un problème sans utiliser de fonctions d'ordre supérieur
const arr1 = [1, 2, 3]; const arr2 = []; for(let i = 0; i < arr1.length; i++) { arr2.push(arr1[i] * 2); } // [ 2, 4, 6 ] console.log(arr2);
Résolution d'un problème à l'aide d'une carte de fonctions d'ordre supérieur
const arr1 = [1, 2, 3]; const arr2 = arr1.map(function(item) { return item * 2; }); console.log(arr2);
Vous pouvez même réduire le volume de ce code si vous utilisez la fonction flèche:
const arr1 = [1, 2, 3]; const arr2 = arr1.map(item => item * 2); console.log(arr2);
Exemple n ° 2
Supposons que nous ayons un tableau contenant l'année de naissance de certaines personnes, et nous devons créer un tableau qui obtiendra leur âge en 2018. Considérez, comme précédemment, la solution à ce problème de deux manières.
Résolution d'un problème sans utiliser de fonctions d'ordre supérieur
const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = []; for(let i = 0; i < birthYear.length; i++) { let age = 2018 - birthYear[i]; ages.push(age); }
Résolution d'un problème à l'aide d'une carte de fonctions d'ordre supérieur
const birthYear = [1975, 1997, 2002, 1995, 1985]; const ages = birthYear.map(year => 2018 - year);
▍ Méthode Array.prototype.filter
La méthode
filter()
crée, sur la base du tableau, un nouveau tableau dans lequel se trouvent les éléments du tableau d'origine, correspondant à la condition spécifiée dans la fonction de rappel passée à cette méthode. Cette fonction prend, comme dans le cas de la méthode
map()
, 3 arguments:
element
,
index
et
array
.
Prenons un exemple construit de la même manière que lorsque l'on considère la méthode
map()
.
Exemple
Supposons que nous ayons un tableau contenant des objets dont les propriétés stockent des informations sur le nom et l'âge des représentants d'un certain groupe de personnes. Nous devons créer un tableau dans lequel il y aura uniquement des informations sur les représentants adultes de ce groupe (ceux dont l'âge a atteint 18 ans).
Résolution d'un problème sans utiliser de fonctions d'ordre supérieur
const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = []; for(let i = 0; i < persons.length; i++) { if(persons[i].age >= 18) { fullAge.push(persons[i]); } } console.log(fullAge);
Résolution d'un problème à l'aide d'un filtre de fonction d'ordre supérieur
const persons = [ { name: 'Peter', age: 16 }, { name: 'Mark', age: 18 }, { name: 'John', age: 27 }, { name: 'Jane', age: 14 }, { name: 'Tony', age: 24}, ]; const fullAge = persons.filter(person => person.age >= 18); console.log(fullAge);
▍ Méthode Array.prototype.reduce
La méthode Reduce
reduce()
traite chaque élément du tableau à l'aide d'un rappel et place le résultat dans une seule valeur de sortie. Cette méthode prend deux paramètres: rappel et valeur initiale facultative (
initialValue
).
Un rappel accepte quatre paramètres:
accumulator
(accumulateur),
currentValue
(valeur actuelle),
sourceArray
(index actuel),
sourceArray
(tableau source).
Si le paramètre
initialValue
est fourni à la
initialValue
, alors, au début de la méthode, l'
accumulator
sera égal à cette valeur et le premier élément du tableau traité sera écrit dans
currentValue
.
Si le paramètre
initialValue
n'est pas fourni à la méthode, le premier élément du tableau sera écrit dans l'
accumulator
et le second dans
currentValue
.
Exemple
Supposons que nous ayons un tableau de nombres. Nous devons calculer la somme de ses éléments.
Résolution d'un problème sans utiliser de fonctions d'ordre supérieur
const arr = [5, 7, 1, 8, 4]; let sum = 0; for(let i = 0; i < arr.length; i++) { sum = sum + arr[i]; }
La résolution d'un problème à l'aide d'une fonction d'ordre supérieur réduit
Tout d'abord, envisagez d'utiliser la méthode
reduce()
sans lui donner une valeur initiale.
const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; });
Chaque fois qu'un rappel est appelé avec une valeur
currentValue
transmise, c'est-à-dire l'élément suivant du tableau, son paramètre
accumulator
s'avère contenir les résultats de l'opération précédente, c'est-à-dire ce qui a été renvoyé par la fonction à l'itération précédente. Après l'achèvement de cette méthode, le résultat final tombe dans la
sum
constante.
Voyons maintenant à quoi ressemblera la solution au problème si nous transmettons la valeur initiale à la méthode
reduce()
.
const arr = [5, 7, 1, 8, 4]; const sum = arr.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 10);
Comme vous pouvez le voir, l'utilisation d'une fonction d'ordre supérieur a rendu notre code plus propre, plus concis et plus facile à lire.
Créez des fonctions personnalisées d'ordre supérieur
Jusqu'à présent, nous avons travaillé avec des fonctions d'ordre supérieur intégrées à JS. Créons maintenant notre propre fonction qui fonctionne avec d'autres fonctions.
Imaginez que JavaScript ne dispose pas d'une méthode de tableau
map()
standard. Nous pouvons créer nous-mêmes une telle méthode, qui se traduira par le développement d'une fonction d'ordre supérieur.
Supposons que nous ayons un tableau de chaînes et que nous aimerions créer sur sa base un tableau avec des nombres, chacun représentant la longueur de la chaîne stockée dans un élément du tableau d'origine.
const strArray = ['JavaScript', 'Python', 'PHP', 'Java', 'C']; function mapForEach(arr, fn) { const newArray = []; for(let i = 0; i < arr.length; i++) { newArray.push( fn(arr[i]) ); } return newArray; } const lenArray = mapForEach(strArray, function(item) { return item.length; });
Dans cet exemple, nous avons créé une fonction d'ordre supérieur
mapForEach
, qui prend un tableau et une fonction de rappel
fn
. La fonction
mapForEach
tableau dans une boucle et appelle le rappel
fn
à chaque itération de cette boucle.
Le rappel
fn
accepte l'élément de chaîne actuel du tableau et renvoie la longueur de cet élément. Ce que la fonction
fn
renvoie est utilisé dans la commande
newArray.push()
et obtient dans le tableau que
mapForEach()
retournera. Ce tableau sera finalement écrit dans la constante
lenArray
.
Résumé
Dans cet article, nous avons parlé des fonctions d'ordre supérieur et exploré certaines des fonctions JavaScript intégrées. De plus, nous avons trouvé comment créer vos propres fonctions d'ordre supérieur.
En résumé, l'essence des fonctions d'ordre supérieur peut être considérée comme des fonctions qui peuvent prendre d'autres fonctions comme arguments et renvoyer d'autres fonctions comme résultats de leur travail. Travailler avec d'autres fonctions dans des fonctions d'ordre supérieur ressemble à travailler avec d'autres objets.
Chers lecteurs! Devez-vous écrire vos propres fonctions d'ordre supérieur?
