L'exemple de cet article décrit l'utilisation de la fermeture javascript (Closure). Partagez-le avec tout le monde pour votre référence, les détails sont les suivants :
closure se traduit par "closure", et j'ai l'impression que cette chose est présentée de manière trop académique. Discutons-en brièvement en faisant référence à des livres et des ressources en ligne (veuillez faire attention à toute compréhension inappropriée).
1. Qu'est-ce que la fermeture
Réponse officielle : La soi-disant « fermeture » fait référence à une expression (généralement une fonction) qui a de nombreuses variables et un environnement lié à ces variables, donc ces variables font également partie de l'expression.
Après avoir lu la définition ci-dessus, si vous n'êtes pas un expert, je crois fermement que vous demanderez avec colère comme moi : est-ce un langage humain tmd ?
Pour comprendre les fermetures, le code est le plus convaincant Voici le code :
function funcTest() { var tmpNum=100; //私有变量 //在函数funcTest内定义另外的函数作为funcTest的方法函数 function innerFuncTest( { alert(tmpNum); //引用外层函数funcTest的临时变量tmpNum } return innerFuncTest; //返回内部函数 } //调用函数 var myFuncTest=funcTest(); myFuncTest();//弹出100
Dans le code ci-dessus, les commentaires ont été écrits clairement. Maintenant, nous pouvons comprendre la « fermeture » comme ceci : définir une autre fonction dans le corps de la fonction comme fonction de méthode de l'objet cible (dans l'exemple, définir une autre fonction innerFuncTest comme fonction de méthode de funcTest dans la fonction funcTest), et la fonction de méthode de cet objet est le contraire. Venons-en à référencer les variables temporaires dans le corps de la fonction externe (la fermeture est un mécanisme permettant de maintenir indirectement les valeurs des variables. Dans l'exemple, la fonction interne innerFuncTest fait référence à la variable temporaire tmpNum de la fonction externe funcTest. Elle Il faut noter ici que les variables temporaires peuvent être incluses dans la fonction externe (toutes les variables locales déclarées, les paramètres et autres fonctions internes déclarées). Lorsqu'une de ces fonctions internes est appelée en dehors de la fonction externe qui les contient, une fermeture est formée (dans l'exemple, lors de l'appel de la fonction, myFuncTest appelle en fait la fonction innerFuncTest, ce qui signifie qu'une fonction interne de funcTest, innerFuncTest est appelée en dehors funcTest, une fermeture est créée).
2. Deux exemples d'utilisation de fermetures
Voici deux exemples. L'un est dû au fait que les fermetures causent des problèmes, et l'autre utilise des fermetures pour lier intelligemment les paramètres via la portée d'une fonction.
Les fragments de balisage HTML liés à ces deux exemples sont les suivants :
<a href="#" id="closureTest0">利用闭包的例子(1秒后会看到提示)</a><br /> <a href="#" id="closureTest1">由于闭包导致问题的例子1</a><br /> <a href="#" id="closureTest2">由于闭包导致问题的例子2</a><br /> <a href="#" id="closureTest3">由于闭包导致问题的例子3</a><br />
(1) Problèmes causés par les fermetures
function badClosureExample(){ for (var i = 1; i <4; i++) { var element = document.getElementById('closureTest' + i); element .onclick = function(){ alert('您单击的是第' + i + '个链接'); } } }
Ensuite, appelez cette fonction après le chargement de la page (sinon une erreur pourrait être signalée) :
window.onload = function(){ badClosureExample(); }
Regardez les résultats en cours d'exécution. Si vous cliquez sur les trois derniers liens, quelles informations verrez-vous dans la boîte d'avertissement ? ——C'est tout "Vous avez cliqué sur le 4ème lien". Cela vous surprend ? Pourquoi?
Analyse : parce que le gestionnaire d'événements attribué à element.onclick dans la fonction badClosureExample(), c'est-à-dire que la fonction anonyme onclick n'est appelée qu'une fois la fonction badClosureExample() terminée (lorsque l'utilisateur clique sur le lien). Lors de l'appel, la variable i doit être évaluée. L'analyseur recherchera d'abord dans le gestionnaire d'événements, mais i n'est pas défini. Ensuite, recherchez dans la fonction badClosureExample(). Elle est définie à ce moment-là, mais la valeur de i est 4 (la boucle for cessera de s'exécuter uniquement si i est supérieur à 4). Par conséquent, cette valeur est obtenue - exactement ce que ferait la fermeture (fonction anonyme) si elle utilisait une variable dans le cadre de sa fonction externe (badClosureExample). De plus, cela est également dû au fait que la fonction anonyme elle-même ne peut pas transmettre de paramètres (et ne peut donc pas conserver sa propre portée).
Alors, comment résoudre le problème dans cet exemple ? En fait, il existe de nombreuses méthodes (autant l'écrire vous-même et voir). Je pense que le code est relativement simple et direct :
function popNum(oNum){ return function(){ alert('您单击的是第'+oNum+'个链接'); } } function badClosureExample(){ for (var i = 1; i <4; i++) { var element = document.getElementById('closureTest' + i); element .onclick =new popNum(i); } }
(2), utilisation intelligente des fermetures pour lier les paramètres
Toujours avec le fragment HTML ci-dessus, nous souhaitons retarder l'apparition d'une boîte d'avertissement lorsque l'utilisateur clique sur le premier lien. Comment y parvenir ? La réponse est d'utiliser la fonction setTimeout(), qui appelle une fonction après un nombre spécifié de millisecondes, comme :
function goodClosureExample(oMsg){ return function(){ alert(oMsg); }; }
La fonction goodClosureExample est utilisée pour renvoyer une fonction anonyme (fermeture). Et nous pouvons faire en sorte que la fonction anonyme renvoyée lie le paramètre en lui passant un paramètre, tel que :
window.onload = function(){ var element = document.getElementById('closureTest0'); if (element) { var good = goodClosureExample('这个参数是由闭包绑定的'); element.onclick = function(){ setTimeout(good, 1000); //延迟1秒弹出提示 } } }
3、javascript的垃圾回收原理
(1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
(2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
在js中使用闭包,往往会给javascript的垃圾回收器制造难题。尤其是遇到对象间复杂的循环引用时,垃圾回收的判断逻辑非常复杂,搞不好就有内存泄漏的危险,所以,慎用闭包。ms貌似已经不建议使用闭包了。
希望本文所述对大家JavaScript程序设计有所帮助。