Qu'est-ce qu'une fermeture?
Regardons d'abord un morceau de code:
fonction a () {var n = 0; function inc () {n ++; console.log (n); } inc (); Inc (); }un(); // Sorties de console 1, puis sort 2C'est simple. Regardons un autre morceau de code:
fonction a () {var n = 0; this.inc = function () {n ++; console.log (n); };} var c = new a (); c.inc (); // sortie de la console 1C.inc (); // sortie de la console 2C'est simple.
Qu'est-ce qu'une fermeture? C'est la fermeture!
Les fonctions qui ont accès à des variables dans le cadre d'une autre fonction sont des fermetures. Ici, la fonction Inc accède à la variable n dans le constructeur A, donc une fermeture est formée.
Regardons un autre morceau de code:
fonction a () {var n = 0; function inc () {n ++; console.log (n); } return inc;} var c = a (); c (); // sortie de la console 1C (); // sortie de la console 2Voyons comment il est exécuté:
var c = Couter (), cette phrase Couter () renvoie la fonction Inc, alors cette phrase est équivalente à var c = inc;
c (), cette phrase est équivalente à inc (); Notez que le nom de la fonction n'est qu'un identifiant (un pointeur vers une fonction), et () est la fonction d'exécution.
Les trois phrases suivantes se sont traduites en: var c = inc; Inc (); inc ();, y a-t-il une différence entre elle et le premier morceau de code? Non.
Qu'est-ce qu'une fermeture? C'est la fermeture!
Tous les tutoriels de manuels aiment utiliser le dernier paragraphe pour illustrer les fermetures, mais je pense que cela complique le problème. Ce qui est renvoyé ici est le nom de la fonction. Les étudiants qui n'ont jamais vu la programmation C / C ++ de Tan Haoqiang peuvent ne pas refléter immédiatement la différence entre amener () ou non, ce qui signifie que cette méthode d'écriture est livrée avec un piège. Bien que cette méthode d'écriture soit plus importante, j'aime toujours singulariser le problème et regarder le code 1 et le code 2. Vous serez toujours confus quant à l'appel de la fonction, serez-vous confus quant à la valeur de n?
Pourquoi avez-vous besoin d'écrire comme ça?
Nous savons que chaque fonction de JS est une petite pièce noire. Il peut obtenir des informations externes, mais le monde extérieur ne peut pas voir directement le contenu à l'intérieur. En mettant la variable N dans une petite pièce sombre, à l'exception de la fonction Inc, il n'y a pas d'autre moyen de contacter la variable n. De plus, la définition de la variable N avec le même nom en dehors de la fonction A ne se affecte pas. Il s'agit de la soi-disant amélioration de "l'encapsulation".
La raison pour laquelle vous devez utiliser la fonction de retour à retour pour identifier Inc est que la fonction Inc ne peut pas être appelée directement en dehors de la fonction A, donc return inc est associé à l'extérieur. Ceci dans le code 2 ne s'associe également qu'à l'extérieur.
Pièges communs
Découvrez ceci:
fonction createFunctions () {var result = new Array (); for (var i = 0; i <10; i ++) {result [i] = function () {return i; }; } Retour Result;} var funcs = createFunctions (); for (var i = 0; i <funcs.length; i ++) {console.log (funcs [i] ());}À première vue, je pensais qu'il sortit 0 ~ 9, mais je ne m'attendais pas à ce qu'il ait sorti 10 10?
Le piège ici est: la fonction avec () est la fonction d'exécution! Une phrase simple var f = function () {alert ('hi'); }; ne apparaîtra pas et la phrase suivante f (); exécutera le code à l'intérieur de la fonction. Le code ci-dessus est traduit par:
var result = new Array (), i; result [0] = function () {return i; }; // La fonction n'est pas exécutée, la fonction reste inchangée et le i dans la fonction ne peut pas être remplacé! résultat [1] = fonction () {return i; }; // La fonction n'est pas exécutée, la fonction reste inchangée et le i dans la fonction ne peut pas être remplacé! ... result [9] = fonction () {return i; }; // La fonction n'est pas exécutée, la fonction reste inchangée et le i dans la fonction ne peut pas être remplacé! i = 10; funcs = résultat; résultat = null; console.log (i); // funcs [0] () consiste à exécuter l'instruction RETRAIT I, qui est pour retourner 10Console.log (i); // funcs [1] () est d'exécuter l'instruction RETOUR I, qui est pour retourner 10 ... console.log (i); // funcs [9] () est d'exécuter l'instruction RETOUR I, c'est-à-dire le retour 10Pourquoi seuls les résultats de la collecte des ordures mais pas moi? Parce que je suis toujours référencé par la fonction. C'est comme un restaurant où les assiettes sont toujours limitées, donc le serveur ira à Patrol Taiwan pour recycler les assiettes vides, mais comment osera-t-il les assiettes qui contiennent encore des légumes? Bien sûr, si vous versez manuellement la vaisselle (= nul) dans l'assiette vous-même, l'assiette sera enlevée. Il s'agit du soi-disant mécanisme de recyclage de la mémoire.
Quant à la façon dont la valeur de je peux encore être conservée, en fait, la lire depuis le début de l'article ne devrait rien être à craindre. N'est-il pas nécessaire de manger un morceau du plat dans l'assiette pour perdre un morceau?
Résumons
Une fermeture est une variable qu'une fonction fait référence à une autre fonction. Étant donné que la variable est référencée, elle ne sera pas recyclée, elle peut donc être utilisée pour encapsuler une variable privée. C'est un avantage et un inconvénient. Les fermetures inutiles n'augmenteront que la consommation de mémoire! De plus, lorsque vous utilisez des fermetures, vous devez également faire attention à la question de savoir si la valeur de la variable répond à vos besoins, car c'est comme une variable privée statique. Les fermetures sont généralement mélangées avec beaucoup de choses, et ce n'est qu'après les avoir contactées avec plus de compréhension que nous pouvons approfondir notre compréhension. Ici, nous parlons de choses de base.
Lien vers cet article: http://www.cnblogs.com/qieguo/p/5457040.html
Ce qui précède concerne cet article, j'espère qu'il sera utile à l'apprentissage de tout le monde.