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

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);
这种写法,就很好的保护了空间变量,不会污染到外面的对象,所有的操作都在闭包内部执行。 以上只是个人前端对于闭包的经验之谈,每个人理解的可能不一样,有不对的地方,可指出来,我加以修正,谢谢。

JavaScript利用闭包循环绑定事件的更多相关文章

  1. dom元素循环绑定事件的技巧

    以前总觉得自己写的代码不太规范,尤其是写原生的时候.举个例子: 要为页面上所有".a"的元素绑定事件,当然了用jquery很方便:$('.a').bind("click& ...

  2. JavaScript利用闭包实现模块化

    利用闭包的强大威力,但从表面上看,它们似乎与回调无关.下面一起来研究其中最强大的一个:模块. function foo() { var something = "cool"; va ...

  3. javascript:使用代理绑定事件

    <ul id="box"> <li>1</li> <li>2</li> <li>3</li> & ...

  4. JavaScript中给onclick绑定事件后return false遇到的问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. js的一个有意思的小题,闭包解决getElementByTagName的for循环绑定事件错误问题

    问: i 会输出什么?改写成闭包的写法? <a href="javaScript:void(0)">a</a> <a href="javaS ...

  6. for循环绑定事件,闭包思想!

    1.选项卡问题 总结:用alert()测试,是否得到对象. 2.闭包,解决作用域. <script> window.onload=function(){ var li=document.g ...

  7. jquery循环绑定事件

    <html> <head> <title></title> <script type="text/javascript" sr ...

  8. Angularjs 中 ng-repeat 循环绑定事件

    用ng-repeat循环是如果有ng-click之类的事件需要传入参数我们一般这样写 <span class='del' ng-click="RemoveCost({{item.Id} ...

  9. javascript闭包传参和事件的循环绑定

    今天看到一个javascript的题目,按常理循环绑定事件,但是得到的结果却不是想要的. <a href="#">text</a><br>< ...

随机推荐

  1. WP8.1小梦词典开发2:百度翻译API使用

    原文出自:http://www.bcmeng.com/api2/ 小梦昨天和大家分享了WP8.1金山词霸API使用方法,今天继续分享windows phone 8.1中百度翻译API的使用方法.和昨天 ...

  2. SpringMVC中@RequestBody引起的400异常处理,返回校验失败具体信息

    问题 使用@RequestBody接收一个json数据的时候,如果传入的参数不符合条件,就会直接返回400的error page. 但究竟是为什么会400并没有抛出来.这对大量参数字段的我们来说,排错 ...

  3. Solr5.2.1+Zookeeper3.4.8分布式集群搭建

    1.选取三台服务器 由于机器比较少,现将zookeeper和solr都部署在以下三台机器上.(以下操作都是在172.16.20.101主节点上进行的哦) 172.16.20.101 主节点 172.1 ...

  4. 【VB超简单入门】五、基本输出输入

    之前讲了VB IDE的基本操作和概念,接下来要开始将VB语言的编程了. 程序最重要的部分是输出和输入,输入数据,经过计算机处理,再输出结果.本文将介绍两种最基本的输出输入方法,分别是Print.Msg ...

  5. Android -- 贝塞尔曲线公式的推导

    1,最近看了几个不错的自定义view,发现里面都会涉及到贝塞尔曲线知识,深刻的了解到贝塞尔曲线是进阶自定义view的一座大山,so,今天先和大家来了解了解. 2,贝塞尔曲线作用十分广泛,简单举几个的栗 ...

  6. Oracle14~23

    14.查询所有学生的Sname.Cno和Degree列. 15.查询所有学生的Sno.Cname和Degree列. 16.查询所有学生的Sname.Cname和Degree列. 17. 查询“9503 ...

  7. opencv配置(win10+VS2015+opencv3.1)

    Step 1:准备工作 a.win10 b.vs2015 c.opencv3.1[从http://opencv.org/downloads.html下载] Step 2.开始安装 a. 双击openc ...

  8. Ubuntu14.04配置Apache支持多个站点

    怎样在一个Ubuntu的机器上(虚拟机)配置Apache支持多个网站呢? 比如你有一台独立的Ubuntu虚拟机,配有一个外网的IP(45.46.47.48),并且注册了两个域名AAA.com和BBB. ...

  9. 性能调优案例分享:Mysql的cpu过高

    性能调优案例分享:Mysql的cpu过高   问题:一个系统,Mysql数据库,数据量变大之后.mysql的cpu占用率很高,一个测试端访问服务器时mysql的cpu占用率为15% ,6个测试端连服务 ...

  10. Xamarin XAML语言教程使用Xamarin Studio创建XAML(二)

    Xamarin XAML语言教程使用Xamarin Studio创建XAML(二) 使用Xamarin Studio创建XAML Xamarin Studio和Visual Studio创建XAML文 ...