La fermeture est une difficulté et une caractéristique du langage Javascript. De nombreuses applications avancées reposent sur la fermeture.
Les fermetures ont trois caractéristiques :
1. Fonction fonction imbriquée
2. Les paramètres et variables externes peuvent être référencés à l'intérieur de la fonction
3. Les paramètres et variables ne seront pas recyclés par le mécanisme de garbage collection
Une fermeture est une fonction qui a accès à des variables dans la portée d'une autre fonction. La manière la plus courante de créer une fermeture est de créer une autre fonction au sein d'une fonction et d'accéder aux variables locales de cette fonction via une autre fonction
L'utilisation de fermetures présente un avantage et un inconvénient, c'est-à-dire que les variables locales peuvent résider en mémoire et éviter d'utiliser des variables globales. Les variables globales sont appelables dans chaque module, ce qui est voué à être désastreux.
Il est donc recommandé d'utiliser des variables locales privées et encapsulées.
Une fois la fonction générale exécutée, l'objet actif local est détruit et seule la portée globale est enregistrée dans la mémoire. Mais la situation des fermetures est différente !
Fermeture des fonctions imbriquées :
function aaa() { var a = 1; return function(){ alert(a++) }; } var fun = aaa(); fun();// 1 执行后 a++,,然后a还在~ fun();// 2 fun = null;//a被回收!!
Le résultat de sortie ci-dessus est 5 ;
Les fermetures garderont toujours les variables en mémoire, ce qui augmentera la consommation de mémoire en cas de mauvaise utilisation.
Principe du garbage collection de JavaScript
(1). En JavaScript, si un objet n'est plus référencé, alors l'objet sera recyclé par GC
(2) Si deux objets font référence l'un à l'autre et ne sont plus référencés par un tiers, alors les deux objets qui font référence l'un à l'autre seront également recyclés.
Alors, quels sont les avantages de l’utilisation des fermetures ? Les avantages de l'utilisation des fermetures sont :
1. Vous voulez qu'une variable réside longtemps en mémoire
2. Évitez la pollution des variables globales
3. L'existence de membres privés
1. Accumulation de variables globales
<script> var a = 1; function abc(){ a++; alert(a); } abc(); //2 abc(); //3 </script>
<script> function abc(){ var a = 1; a++; alert(a); } abc(); //2 abc(); //2 </script>
Alors, comment pouvons-nous faire d’une variable à la fois une variable locale et cumulative ?
3. Accumulation de variables locales (ce que les fermetures peuvent faire)
<script> function outer(){ var x=10; return function(){ //函数嵌套函数 x++; alert(x); } } var y = outer(); //外部函数赋给变量y; y(); //y函数调用一次,结果为11 y(); //y函数调用第二次,结果为12,实现了累加 </script>
Déclaration de fonction et expression de fonction en js :
En js on peut déclarer une fonction via le mot-clé function :
<script> function abc(){ alert(123); } abc(); </script>
On peut également transformer cette déclaration en expression via un "()":
<script> (function (){ alert(123); })(); //然后通过()直接调用前面的表达式即可,因此函数可以不必写名字; </script>
4. Code modulaire pour réduire la pollution des variables globales
<script> var abc = (function(){ //abc为外部匿名函数的返回值 var a = 1; return function(){ a++; alert(a); } })(); abc(); //2 ;调用一次abc函数,其实是调用里面内部函数的返回值 abc(); //3 </script>
5. L'existence de membres privés
<script> var aaa = (function(){ var a = 1; function bbb(){ a++; alert(a); } function ccc(){ a++; alert(a); } return { b:bbb, //json结构 c:ccc } })(); aaa.b(); //2 aaa.c() //3 </script>
6. Trouver directement l'index de l'élément correspondant dans la boucle
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ //当点击时for循环已经结束 alert(i); }; } } </script> </head> <body> <ul> <li>123</li> <li>456</li> <li>789</li> <li>010</li> </ul> </body> </html>
7. Réécrivez le code ci-dessus en utilisant la fermeture :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for (var i=0;i<aLi.length;i++){ (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i); } }; </script> </head> <body> <ul> <li>123</li> <li>456</li> <li>789</li> </ul> </body> </html>