Passer au contenu principal

Les Closures en JavaScript

Les closures sont un concept fondamental en JavaScript qui permettent à une fonction d'accéder à des variables définies en dehors de son propre bloc. Elles jouent un rôle clé dans la gestion de l'état et l'encapsulation des données.

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 variable count 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 de outer.

  • count est préservé en mémoire et son état est maintenu à travers plusieurs appels de increment.

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.