Les Closures en JavaScript
Fonction classique vs Closure
Exemple d'une fonction classique
Prenons une fonction simple qui calcule la somme de deux nombres :
function somme(a, b) {
return a + b;
}
Cette fonction dépend uniquement des arguments a
et b
passés lors de son exécution. Lorsque la fonction est appelée, elle est ajoutée à la Call Stack où elle s'exécute, puis ses variables internes sont libérées une fois son exécution terminée.
Exemple d'une closure
Voyons maintenant un exemple où une fonction dépend d'une variable définie en dehors de son propre bloc :
let b = 2;
function somme(a) {
return a + b;
}
Ici, somme
accède à b
, qui est déclarée dans l'environnement global. Cette variable n'est pas supprimée une fois la fonction exécutée, car JavaScript conserve une référence à b
dans une mémoire spécifique appelée Heap Memory. Elle restera accessible tant qu'il existe une référence active vers elle.
Closure avec une fonction encapsulée
Les closures sont particulièrement puissantes lorsqu'une fonction interne est renvoyée par une fonction externe, capturant ainsi l'état des variables locales.
function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}
const increment = outer();
increment(); // Affiche 1
increment(); // Affiche 2
increment(); // Affiche 3
console.log(increment.count); // Affiche undefined
Dans cet exemple :
-
outer
crée une variablecount
qui est privée car elle est déclarée dans son propre contexte. -
inner
, qui est une closure, peut toujours accéder àcount
même après l'exécution deouter
. -
count
est préservé en mémoire et son état est maintenu à travers plusieurs appels deincrement
.
Avantages des Closures
Encapsulation et variables privées
Les closures permettent d'encapsuler des données, un concept similaire à l'encapsulation en programmation orientée objet (POO). Toute variable déclarée à l'intérieur d'une closure est inaccessible depuis l'extérieur, ce qui empêche les modifications involontaires.
Maintien de l'état des variables
Les closures permettent de conserver l'état des variables d'une exécution à l'autre. Cependant, elles nécessitent plus de mémoire que des fonctions classiques car elles conservent des références aux variables, empêchant ainsi leur libération tant qu'elles sont utilisées.
Utilisation dans les Callbacks et les API
Les closures sont largement utilisées dans les callbacks et les fonctions asynchrones. Exemple :
function fetchData(callback) {
let data = "Données récupérées";
setTimeout(() => {
callback(data);
}, 1000);
}
fetchData(function(result) {
console.log(result); // Affiche "Données récupérées" après 1 seconde
});
Dans cet exemple, la fonction callback est une closure qui capture la variable data et l'utilise après un délai.