我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用。
1.首先我们举一个简单的例子。
html部分:
<a href="#">首页</a>
<a href="#">作品</a>
<a href="#">文章</a>
<a href="#">工具</a>
<a href="#">招聘</a>
<a href="#">赛事</a>
<a href="#">更多</a>
js部分:
var a = document.getElementsByTagName("a"); for(var i =0; i<a.length; i++){ a[i].onclick = function(){ alert(i); } }
现在如果点击“首页”链接,大家认为会弹出什么数字? 答案是7,因为循环绑定以后,i最终为7,所以打印出来的结果就是 7
2.下面我们使用闭包进行封装一次。
var a = document.getElementsByTagName("a"); for(var i =0; i<a.length; i++){ a[i].onclick = (function(i){ return function(){alert(i);} })(i); }
此时,再次进行测试,点击超链接以后,弹出对应的索引值,这就是闭包的作用之一,闭包引用外部变量后,暂时不会被系统回收,onclick后面的代码即为:立即执行一个函数,并且将i变量传递进去,执行函数的时候,内部返回了一个函数,同时,返回的函数内部会引用该参数,因而锁定了此变量。当年点击某一个a链接时,就会执行此return 后面的函数,弹出对应的结果。
闭包简单的说,就是方法里面套方法,最终形成闭包,那么经过我个人的总结经验,闭包的作用主要有:
A:使用闭包可以访问某函数的局部变量,同时这些变量都一直存在于内存中。例如:
function func1(){
var n=999;
}
alert(n); // error
使用闭包后:
function func1(){
var n=999;//局部变量,外部函数无法访问
function func2(){
alert(n);
}
return func2;//返回内部函数
}
var result=func1();
result(); // 999
此时,可借助于闭包访问f1函数的内部变量n,这就是闭包的功效之一,可以访问某函数的局部变量。
B:防止空间污染。闭包中的变量不会被外界访问,因而,内部和外部是隔断的,从而减少变量重复带来的困惑。
闭包的不好之处:
如果闭包引用外部变量,则此变量会一直存在于内存当中,从而降低性能,这也就是为什么,使用闭包循环绑定事件后,点击会弹出对应数字的效果了。
另外,很多Jquery插件再开发的过程中,都会使用闭包,如下:
(function($){ //to-do ...})(jQuery);这种写法,就很好的保护了空间变量,不会污染到外面的对象,所有的操作都在闭包内部执行。 以上只是个人前端对于闭包的经验之谈,每个人理解的可能不一样,有不对的地方,可指出来,我加以修正,谢谢。