Closures
Vous connaissez déjà la portée (scope) : depuis ici, quels noms sont visibles. Un pas de plus : une fonction interne peut encore utiliser un nom extérieur après la fin de l’appel extérieur. Ce lien durable s’appelle une closure.
Ce qu’une closure signifie
Une closure se forme quand une fonction est créée dans une autre et atteint encore plus tard les liaisons de la fonction extérieure. L’appel extérieur peut être terminé ; la fonction interne « se souvient » quand même de ces noms. Vous n’écrivez pas le mot closure dans le code — vous écrivez des fonctions imbriquées, et JavaScript garde vivantes les liaisons extérieures nécessaires.
Trois pièces à surveiller
📊 Fonction extérieure, liaison et fonction intérieure
| Pièce | Rôle | Indice débutant |
|---|---|---|
| fonction extérieure | s’exécute une fois (ou plus) et renvoie souvent une intérieure | l’appel de « mise en place » |
| liaison extérieure | un paramètre ou let / const dans l’extérieure |
la valeur dont l’intérieure a encore besoin |
| fonction intérieure | utilise cette liaison quand vous l’appelez plus tard | la fonction que vous gardez |
Si vous pouvez montrer ces trois, vous expliquez presque tout exemple de closure pour débutants. La surprise n’est pas l’imbrication — c’est que la liaison extérieure reste utile après le return extérieur.
function makeLine(title) {
function show() {
console.log(title);
}
show();
}
makeLine("Shop");
Pendant l’appel, l’intérieure regarde vers l’extérieur
show n’a pas de title local. La recherche marche vers l’extérieur jusqu’à makeLine et trouve le paramètre. C’est une portée imbriquée ordinaire. Les closures vont plus loin : gardez show (ou sa jumelle) pour plus tard, une fois que makeLine est revenue.
function makeLine(title) {
return function show() {
console.log(title);
};
}
let printShop = makeLine("Shop");
printShop();
L’appel extérieur finit — la mémoire reste
makeLine("Shop") renvoie une fonction. Quand vous appelez printShop plus tard, elle affiche encore Shop. Le paramètre title de cet appel terminé reste accessible. Cette capture durable est la closure.
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hiSara = makeGreeter("Sara");
console.log(hiSara());
Les fabriques renvoient une fonction prête
makeGreeter est une petite fabrique : un appel extérieur, une fonction sur mesure en retour. hiSara salue toujours Sara parce qu’elle a fermé sur ce name. Changez l’argument de makeGreeter, obtenez un autre salueur — même schéma, nouvelle mémoire.
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let tick = makeCounter();
console.log(tick());
console.log(tick());
État quasi privé avec un compteur
n vit dans la fonction extérieure. Le code extérieur ne touche pas n directement — seule la fonction renvoyée le peut. Le premier appel renvoie 1, le second 2. Le compteur « se souvient » sans variable globale.
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let a = makeCounter();
let b = makeCounter();
console.log(a());
console.log(a());
console.log(b());
Chaque appel extérieur a sa mémoire
a et b viennent d’appels makeCounter() distincts, donc chacun a son propre n. Deux pas sur a ne font pas démarrer b au milieu. Les closures ne partagent pas automatiquement un sac d’état sauf si vous partagez volontairement une liaison extérieure.
Afficher une valeur fermée sur la page
Construisez un salueur avec la fabrique, appelez-le une fois, et placez la chaîne renvoyée dans un paragraphe.
<!DOCTYPE html>
<html>
<head>
<title>closures — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hi = makeGreeter("Omar");
let box = document.getElementById("msg");
box.textContent = hi();
</script>
</body>
</html>
Le paragraphe affiche Hello, Omar. L’appel extérieur est fini ; hi connaît encore name. Changez seulement la chaîne passée à makeGreeter, actualisez, lisez la nouvelle ligne. Suite : objets — des valeurs liées sous un seul nom.
Exercices
- Écrivez une fonction qui renvoie une intérieure qui journalise un paramètre extérieur.
- Stockez cette fonction renvoyée et appelez-la après la fin de l’appel extérieur.
- Construisez
makeGreeter("Lina")et journalisez la chaîne renvoyée. - Créez un compteur ; appelez-le deux fois et vérifiez
1puis2. - Créez deux compteurs ; n’avancez que le premier deux fois et vérifiez que le second démarre à
1. - Dans la démo HTML, changez seulement l’argument du nom, actualisez, lisez le paragraphe.
Pièges fréquents
- Supposer que les locaux extérieurs disparaissent dès le
return— l’intérieure peut encore les voir - Attendre que chaque
makeCounter()partage un seuln— chaque appel a en général sa mémoire - Croire que « closure » signifie seulement le mot
return—returnpeut renvoyer l’intérieure, mais la mémoire est la liaison fermée - Mettre toute valeur mémorisée sur l’objet global « pour simplifier »
- Attendre ici la leçon complète sur les objets — regrouper des propriétés sous une valeur est la page suivante
Résumé
- Une closure laisse une fonction interne utiliser des noms extérieurs après la fin de l’appel extérieur
- Vous écrivez des fonctions imbriquées ; JavaScript garde vivantes les liaisons nécessaires
- Les fabriques renvoient une fonction sur mesure qui se souvient des valeurs de préparation
- Les compteurs cachent un
nprivé derrière la fonction renvoyée - Des appels extérieurs séparés signifient en général des mémoires séparées
- La page peut afficher une chaîne produite par un nom fermé
- Suite : objets — valeurs liées sous un nom
🧠 Testez Vos Connaissances
Testez Vos Connaissances
Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet
📝 Instructions
- Lisez chaque question attentivement
- Sélectionnez la meilleure réponse pour chaque question
- Vous pouvez refaire le quiz autant de fois que vous le souhaitez
- Votre progression sera affichée en haut