La closure est une difficulté majeure en JavaScript, et c'est aussi une de ses caractéristiques. De nombreuses applications avancées reposent sur les closures.
1. Portée des variables
Pour comprendre les closures, vous devez d'abord comprendre la portée particulière des variables en JavaScript.
Il n'existe que deux types de portée de variable : les variables globales et les variables locales.
La particularité de JavaScript est que les fonctions peuvent directement lire les variables globales en leur sein, mais les variables locales à l'intérieur d'une fonction ne peuvent pas être lues à l'extérieur de la fonction.
Remarque :Lorsque vous déclarez des variables à l'intérieur d'une fonction, assurez-vous d'utiliser l'instruction var. Si vous ne le faites pas, vous déclarez en réalité une variable globale !
2. Comment lire de l'extérieur les variables locales à l'intérieur d'une fonction ?
Pour diverses raisons, nous avons parfois besoin d'accéder aux variables locales à l'intérieur d'une fonction. Cependant, comme mentionné ci-dessus, dans des circonstances normales, c'est impossible ! Cela ne peut être réalisé que par des contournements.
C'est-à-dire, définir une autre fonction à l'intérieur de la fonction.
function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
Dans le code ci-dessus, la fonction f2 est incluse à l'intérieur de la fonction f1. À ce stade, toutes les variables locales à l'intérieur de f1 sont visibles pour f2. Mais l'inverse n'est pas vrai ; les variables locales à l'intérieur de f2 ne sont pas visibles pour f1.
C'est la structure de « chaîne de portées » propre à JavaScript.
Les objets enfants vont rechercher niveau par niveau pour trouver les variables de tous les objets parents. Par conséquent, toutes les variables de l'objet parent sont visibles pour les objets enfants, mais pas l'inverse.
Puisque f2 peut lire les variables locales de f1, du moment que nous renvoyons f2 comme valeur de retour, ne pouvons-nous pas lire les variables internes de f1 depuis l'extérieur de f1 ?
3. Le concept de fermetures
La fonction f2 dans le code ci-dessus est une fermeture.
Les définitions des fermetures dans divers ouvrages spécialisés sont très abstraites. Ma compréhension est la suivante : une fermeture est une fonction qui peut lire les variables internes d'autres fonctions.
Comme en JavaScript, seules les sous-fonctions à l'intérieur d'une fonction peuvent lire les variables locales, une fermeture peut simplement être comprise comme « une fonction définie à l'intérieur d'une autre fonction ».
Ainsi, par essence, une fermeture est un pont qui relie l'intérieur d'une fonction à l'extérieur de la fonction.
4. Utilisations des fermetures
Les fermetures peuvent être utilisées à de nombreux endroits. Elles ont deux utilisations principales : l'une est de lire les variables à l'intérieur d'une fonction comme mentionné précédemment, et l'autre est de garder les valeurs de ces variables en mémoire à tout moment, sans qu'elles soient automatiquement effacées après l'appel de f1.
Pourquoi cela ? La raison est que f1 est la fonction parente de f2, et que f2 est affectée à une variable globale. Cela fait que f2 reste toujours en mémoire, et l’existence de f2 dépend de f1, donc f1 reste également toujours en mémoire et ne sera pas collectée par le mécanisme de ramasse-miettes après la fin de l’appel.
Un autre endroit remarquable dans ce code est"nAdd=function(){n+=1}"Cette ligne. Premièrement, le mot-clé var n’est pas utilisé devant nAdd, donc nAdd est une variable globale, et non une variable locale. Deuxièmement, la valeur de nAdd est une fonction anonyme, et cette fonction anonyme est elle aussi une fermeture, donc nAdd équivaut à un setter qui peut agir sur les variables locales à l’intérieur de la fonction depuis l’extérieur de la fonction.
5. Points à noter lors de l’utilisation de fermetures
- (1) Comme les fermetures font que les variables des fonctions sont conservées en mémoire, la consommation de mémoire est élevée, donc il ne faut pas abuser des fermetures, sinon cela causera des problèmes de performance de la page web et pourra entraîner des fuites de mémoire dans IE. La solution consiste à supprimer toutes les variables locales inutilisées avant de quitter la fonction.
- (2) Les fermetures peuvent modifier les valeurs des variables à l’intérieur de la fonction parente depuis l’extérieur de la fonction parente. Par conséquent, si vous utilisez la fonction parente comme objet, la fermeture comme sa méthode publique et les variables internes comme ses propriétés privées, vous devez faire attention à ne pas modifier sans précaution les valeurs des variables à l’intérieur de la fonction parente.
Lien original : https://www.cnblogs.com/cxying93/p/6103375.html