JavaScript利用闭包循环绑定事件

  

我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用。

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);
这种写法,就很好的保护了空间变量,不会污染到外面的对象,所有的操作都在闭包内部执行。

以上只是个人前端对于闭包的经验之谈,每个人理解的可能不一样,有不对的地方,可指出来,我加以修正,谢谢。
原文地址:https://www.cnblogs.com/jacksoft/p/5619913.html