首页 > 代码库 > 闭包初窥
闭包初窥
先扯一段和代码无关的话题。long long ago,我还是个英语很溜的孩子,当然现在也不是很差。学英语的时候,我几乎不听老师的语法讲解,但是我就是不会用错。写代码亦是如此,我不会关心代码为何要这么写,随心所欲。所以我不会去关注闭包实现的原理,只会关心它的用处。so 不要问我闭包为什么这么写,我也不会告诉你什么是闭包。
闭包到底有什么用?先看一个很经典的例子。
1 <!DOCTYPE html> 2 <head> 3 </head> 4 <body> 5 <li> 0 </li> 6 <li> 1 </li> 7 <li> 2 </li> 8 <li> 3 </li> 9 </body>10 </html>
如上代码的基础下写一段js,使得鼠标点击相应的<li>标签,弹出相应的数字。不假思索,几行代码呼之而出。
1 var list = document.getElementsByTagName(‘li‘);2 for(var i=0; i<4; i++) {3 list[i].onclick = function() {4 alert(i);5 };6 }
代码报错如下:Uncaught TypeError: Cannot set property ‘onclick‘ of undefined 。再一思索,js在dom还没加载前就加载了,需要加上window.onload或者Jq的$(document).ready。修改后的代码如下:
1 window.onload = function() {2 var list = document.getElementsByTagName(‘li‘);3 for(var i=0; i<4; i++) {4 list[i].onclick = function() {5 alert(i);6 };7 }8 };
but一试,弹出的全是4,与初衷相违背。为什么会这样呢,因为你在鼠标点击标签执行click事件的时候,i早已经循环变成了4!怎么办?你可以污染dom,但是最好的办法是使用闭包。这时闭包的用处就是把变量暂时储存在内存中。修改后如下:
1 window.onload = function() { 2 var list = document.getElementsByTagName(‘li‘); 3 for(var i=0; i<4; i++) { 4 (function(i) { 5 list[i].onclick = function() { 6 alert(i); 7 }; 8 })(i); 9 }10 };
至此,大功告成。代码成功地用了一个匿名函数传递并储存了变量。
该写法其他方面的用处。比如在一个for循环中有定时器,而定时器中要使用循环中的i,这时就可以用闭包把i暂时储存在内存中以便定时器结束后能调用;还有是在循环做ajax的时候,ajax的回调可能要用到循环中的i,这时也可以写成闭包的形式。
1 for(var i=1; i<=5; i++) { 2 (function (i){ 3 jQuery.ajax ({ 4 type: ‘GET‘, 5 url: ‘https://www.xinhehui.com/Financing/Invest/ajaxplist?bid_st=0&time_limit=0&rate=0&start_amount=0&prj_safeguards=0&repay_way=0&guarantor_id=&order=&c=1&p=‘ + i, 6 dataType: ‘html‘, 7 async: false, // 同步,执行完当前ajax才执行下一个,一步步往下执行 8 success: function (msg) { 9 setTimeout(function() {console.log(i)}, 2000);10 }11 });12 })(i);13 }
闭包初窥
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。