Une fonction fléchée (ou « arrow function ») en JavaScript est un moyen plus simple d’écrire une fonction. Elle utilise la syntaxe =>
(d’où son nom).
Voici un exemple entre une fonction et sa version fléchée
function addition(a, b) {
return a + b;
}
console.log(addition(2, 3)); // Affiche 5
const addition = (a, b) => {
return a + b;
};
console.log(addition(2, 3)); // Affiche 5
Pour la « nommer » on la met dans une variable. Car en js une variable peut accueillir une fonction.
Quand il n’y a qu’une seule ligne avec un return comme ici on peut directement écrire :
const addition = (a, b) => a + b;
console.log(addition(2, 3)); // Affiche 5
Sans les accolades, javascript comprend qu’il doit return ce qu’il y a derrière.
Ici on a des arguments mais on peut très bien écrire une fonction fléchée sans argument :
const sayHello = () => alert('hello ! ');
sayHello();
En plus d’apporter une syntaxe simplifiée cela apporte un avantage de scope.
function crée son propre contexte, donc le mot clef this dans function fait référence au contexte de la function et non à celui qui l’englobe.
Ce sera plus clair avec un exemple !
function Personne() {
this.name = "Jhon";
setInterval(function sayIExist() {
console.log('Hey my name is ' + this.name);
}, 1000);
}
const john = new Personne(); // affiche chaque seconde "Hey my name is undefined"
Ici chaque seconde on aura « Hey my name is undefined » car this fait référence au contexte de la function sayIExist et non au contexte de Personne.
C’est pour cela qu’avant on retrouvait souvent le trick de mettre le contexte parent dans une variable en principe nommée self :
function Personne() {
this.name = "Jhon";
var self = this;
setInterval(function sayIExist() {
console.log('Hey my name is ' + self.name);
}, 1000);
}
const john = new Personne(); // affiche chaque seconde "Hey my name is Jhon"
Ici la variable a une portée qui lui permet d’être utilisée dans la fonction. Mais ce n’est pas propre malgré que c’était la seul solution avant les fonction fléchées.
Avec l’arrow function on ne change pas de contexte (scope) donc this reste celui de Personne().
function Personne() {
this.name = "Jhon";
setInterval(() => {
console.log('Hey my name is ' + this.name);
}, 1000);
}
const john = new Personne(); // affiche chaque seconde "Hey my name is Jhon"
Et c’est bien plus concis !
L’avantage des fonctions fléchées est encore plus visible quand on utilise des fonctions qui reçoivent des fonctions en paramètre. Voyons l’exemple avec .map :
const pets = ['cat', 'dog', 'zebra'];
const petsInCaps = pets.map(function (item){
return item.touppercase();
});
console.log(petsInCaps);
const pets = ['cat', 'dog', 'zebra'];
const petsInCaps = pets.map((item) => item.touppercase());
console.log(petsInCaps);
Aller plus loin…
En javascript une fonction peut retourner une fonction.
Avec ce concept on peut facilement chainer des fonctions fléchées ce qui nous permet de créer des outils très utiles. Attention toutefois à ne pas créer trop de complexité non plus avec ce concept.
Regardez cet exemple nous allons l’analyser tout de suite après
const asc = (attr) => (a, b) => a[attr] - b[attr];
const animals = [
{ name : "dog", age : 8 },
{ name : 'cat', age : 5 },
{ name : 'zebra', age: 6 }
];
const animalsOrderedByAge = animals.sort(asc('age'));
console.log(animalsOrderedByAge);
La première chose à se rappeler c’est que la fonction .sort attends une fonction qui doit recevoir 2 paramètres a et b afin de les comparer pour indiquer lequel vient en premier.
L’idée revient à faire cela :
animals.sort(function(a,b){
return a - b;
});
Soit en version fléchée :
animals.sort((a,b) => a - b);
Le problème que l’on a c’est que l’on utilise des objets et que l’on veut indiquer la propriété à prendre compte : age.
On a donc créé une fonction qui reçoit en paramètre le nom de la propriété et qui va retourner la fonction qu’attend map.
La version function serait vraiment très verbeuse :
function asc(attr){
return function (a, b){
return a[attr] - b[attr];
}
}
Alors qu’en fléchée…
const asc = (attr) => (a, b) => a[attr] - b[attr];
Biensûr dans l’idéal il faudra ajouter des vérifications que attr existe bien dans a et b. On peut également attribuer une valeur par défaut à attr : (attr = ‘default’) etc…les clefs sont maintenant entre vos mains !
Laisser un commentaire