Bonjour.
J’ai crois avoir assimilé le principe des fermetures ( closures), en tout cas en théorie. Mais je n’ai pas encore vraiment compris à quoi cela pouvait servir en pratique. Auriez-vous des exemples ? Des cas on ne peut pas faire sans ou au moins pour lesquels il est vraiment beaucoup plus simple d’utiliser des fermetures ?
Merci d’avance.
P.B.
Bonjour @pbejian ,
Voici une liste d’exemples non exhaustifs de fonctionnalités qui ne seraient pas réalisables si toutes les fonctions en JavaScript (à l’exception de celles créées avec new Function()
) n’étaient pas des fermetures.
Ceux-ci proviennent d’un des articles de mon blog intégralement consacré aux fermetures en général et ensuite spécifiquement aux fermetures en JavaScript.
Usage pratique des fermetures
Dans la pratique les fermetures permettent la création de structures élégantes, permettant la personnalisation de différents calculs définis par un argument fonctionnel. En voici des exemples non exhaustifs.
Argument fonctionnel
Voici un exemple avec la méthode sort
des tableaux qui accepte en tant que premier paramètre un argument fonctionnel de « condition de tri » :
Code JavaScript
[1, 2, 3].sort(function (a, b) {
// ... conditions de tri de votre choix
});
Voici un autre exemple avec la méthode find
. Il est parfois intéressant d’utiliser des fonctions de recherche en utilisant des arguments fonctionnels définissant les conditions de recherche :
Code JavaScript
someCollection.find(function (element) {
return element.someProperty === 'condition de recherche';
});
Association fonctionnelle
Voici un exemple de ce que l’on appel de l’association fonctionnelle (« mapping functionnals ») avec la méthode map
d’un tableau. Celle-ci va associer à un nouveau tableau une valeur calculée à chaque élément :
Code JavaScript
[1, 2, 3].map(function (element) {
return element * 2;
}); // `[2, 4, 6]`
Boucle de fonction
Il est aussi intéressant d’autres fois d’appliquer les fonctions fonctionnelles, par exemple, dans une méthode forEach
qui applique des instructions pour chaque élément d’un tableau :
Code JavaScript
[1, 2, 3].forEach(function (element) {
if (element % 2 !== 0) {
console.log(element);
}
});
// affiche `1`
// affiche `3`
apply
et call
Au passage, les méthodes de fonction apply
et call
utilisent également des arguments fonctionnels. Nous avons déjà discuté de ces méthodes dans une note à propos de la valeur de this mais ici, nous allons voir leurs rôles avec les arguments fonctionnels ou fonctions appliquées en tant qu’argument (à une liste d’arguments avec apply
et des positions d’argument avec call
) :
Code JavaScript
(function () {
console.log([].join.call(arguments, ';'));
}).apply(this, [1, 2, 3]);
// affiche `1;2;3`
Appel différés
Un autre point important des fermetures sont la possibilité des appels différés (« deferred calls ») :
Code JavaScript
var a = 10;
setTimeout(function () {
console.log(a);
}, 1000);
// une seconde d'attente...
// ...puis affichaqe de `10`
Fonction de rappel
Plus simplement, un cas d’usage rependu des fermetures est celui des fonctions de rappel (« callback functions ») :
Code JavaScript
// ...
var x = 10;
xmlHttpRequestObject.onreadystatechange = function () {
// la fonction de rappel est appelée en différé,
// quand les données sont prêtes.
// La variable `x` est ici disponible indépendamment
// du fait que lorsque le contexte interne existe,
// l'exécution du code externe est déjà fini.
console.log(x); // `10`
};
// ...
Encapsulations privées
Les fermetures servent également à « masquer » des variables dans une portée encapsulante lors de l’exécution d’instructions :
Code JavaScript
var resitentEvil = {};
// initialisation
(function (object) {
var veronica = 10;
object.getVirus = function _getVirus() {
return veronica;
};
})(resitentEvil);
console.log(resitentEvil.getVirus()); // retourne la valeur `veronica` enfermée : `10`
console.log(veronica); // « erreur : `veronica` n'est pas défini(e) »