# Programmation JavaScript/Fermeture

* Introduction
    Programmer en deux minutes
*   * Page wiki
*   * Compteur en temps réel
*   * Site dans un document
* Outils de développement
* Syntaxe
** Ligne d'instruction
** Ordre d'évaluation
** Bloc d'instructions
** Identificateurs
** Expression littérale
** Commentaire
** Mots réservés
** Variables
** Opérateurs
** Structures de contrôle
** Exceptions et erreurs
** Fonctions utilisateur
** Évènement
* Objets prédéfinis
** window
** document
** navigator
** Array
** Boolean
** Date
** Error
** Function
** Math
** Number
** Object
** String
** Element
** RegExp
* Fonctions prédéfinies
* Programmation avancée
** Opérateurs de bits
** Fermeture
** Programmation objet
** Notation JSON
** AJAX
** Stockage
** Générateurs
** Interface DOM
** Objets Microsoft
* Frameworks
** Dojo
    Hello World
    Widgets
    Ressources
** jQuery
** Node.js
** React.js
* Tests
** Ava
** Jest
** Cypress
* Débogage
* Erreurs connues
* Références
* Introduction
    Programmer en deux minutes
*   * Page wiki
*   * Compteur en temps réel
*   * Site dans un document
* Outils de développement
* Syntaxe
** Ligne d'instruction
** Ordre d'évaluation
** Bloc d'instructions
** Identificateurs
** Expression littérale
** Commentaire
** Mots réservés
** Variables
** Opérateurs
** Structures de contrôle
** Exceptions et erreurs
** Fonctions utilisateur
** Évènement
* Objets prédéfinis
** window
** document
** navigator
** Array
** Boolean
** Date
** Error
** Function
** Math
** Number
** Object
** String
** Element
** RegExp
* Fonctions prédéfinies
* Programmation avancée
** Opérateurs de bits
** Fermeture
** Programmation objet
** Notation JSON
** AJAX
** Stockage
** Générateurs
** Interface DOM
** Objets Microsoft
* Frameworks
** Dojo
    Hello World
    Widgets
    Ressources
** jQuery
** Node.js
** React.js
* Tests
** Ava
** Jest
** Cypress
* Débogage
* Erreurs connues
* Références
[ Modifier le sommaire ]
Une fermeture ou clôture (appelée closure en anglais) est une fonction accompagnée de son environnement lexical. L'environnement lexical d'une fonction est l'ensemble des variables non locales qu'elle a capturées, soit par valeur (c'est-à-dire par copie des valeurs des variables), soit par référence (c'est-à-dire par copie des adresses mémoires des variables). Une fermeture est donc créée, entre autres, lorsqu'une fonction est définie dans le corps d'une autre fonction et utilise des paramètres ou des variables locales de cette dernière.
Une fermeture peut être passée en argument d'une fonction dans l'environnement où elle a été créée (passée vers le bas) ou renvoyée comme valeur de retour (passée vers le haut). Dans ce cas, le problème posé alors par la fermeture est qu'elle fait référence à des données qui auraient typiquement été allouées sur la pile d'exécution et libérées à la sortie de l'environnement. Hors optimisations par le compilateur, le problème est généralement résolu par une allocation sur le tas de l'environnement.

## Itérations

En javascript, il est possible de créer explicitement des fermetures pour conserver des valeurs dans un contexte particulier. Par exemple, dans une fonction qui crée des boutons dans une boucle en définissant une fonction d'écoute du clic de l'utilisateur a besoin d'utiliser une fermeture.
La fonction de l'exemple ci-dessous crée des boutons pour ouvrir des panneaux cachés initialement, sans utiliser de fermeture :
Le problème est visible lorsque la page contient plusieurs boutons et plusieurs panels : tous les boutons n'activent que le dernier panel et seul le dernier bouton change d'état même si c'est un autre bouton qui est cliqué.
La cause est la fonctionnalité hoisting de Javascript : les déclarations de variables avec var sont remontées au niveau de la fonction. Le code précédent est interprété comme ceci :
Il est facile de comprendre la cause du problème : lors de l'appel à la fonction, les variables bouton et panel sont les mêmes pour toutes les fonctions d'écoute et contiennent les valeurs qui leurs ont été assignées lors de la dernière itération. Seuls le dernier bouton et le dernier panel sont donc fonctionnels.
La solution est de forcer la création de nouvelles variables à chaque itération pour conserver les valeurs assignées, utilisées par les fonctions d'écoute des différents boutons. Pour cela, une fermeture est nécessaire :
Le bloc d'instruction est encapsulé dans une fonction anonyme, appelée immédiatement. Les variables qui y sont déclarées sont déjà au niveau le plus haut de la fonction. Les valeurs qui leurs sont assignées proviennent des variables locales de la fonction englobante et sont les copies des valeurs au moment de l'appel à la fonction anonyme durant l'itération de la boucle for.
En JavaScript 6 (EcmaScript 6), il est possible d'utiliser let ou const à la place de var pour déclarer les variables, car le hoisting n'est pas opérant avec ces mots-clés.

## Créer des fonctions de manière dynamique

Les fermetures peuvent être utilisées aussi pour créer des fonctions de manière dynamique, comme l'exemple ci-dessous créant des fonctions multiplicatrice par un facteur passé en argument.
Comme une fonction est utilisable comme n'importe quel type de données en JavaScript, on peut écrire :
En ES6 :