浅谈js中的闭包


Posted in Javascript onMarch 16, 2015

首先我们先来看一段代码:

<a href="javascript:void(0);">111</a>

<a href="javascript:void(0);">222</a>

<a href="javacsript:void(0);">333</a>

var a=document.getElementsByTagName("a");
function b(){


for(var i=0;i<a.length;i++){


a[i].onclick=function(){



alert(i);


}


}

}

按照我们设计的初衷,应该是点击一个a标签就相应的弹出该标签的序列号,即点击第一个a就弹出0,点击第二个就弹出1...但是事实是弹出的始终是a标签的个数,这是什么原因呢?这个问题困扰了我很久,查阅了许多网上的资料还有参考书籍,大多说的似是而非,相信也有许多同学对其中原因也不甚了解,就这个问题我谈谈自己的理解,如有不当之处,还请批评指正。

就我个人的理解,上述函数未能达到目的的原因是,事件处理函数绑定了变量i,而该事件处理函数又赋值给了onclick,即是说只有在点击a标签的时候才会调用该函数,因此从逻辑上来说,在单纯的for循环里面function(){alert(i);}这段函数实际上是没有执行的,而当我们点击a标签的时候for循环早就已经执行完毕,此时i的值就是for循环执行完毕的终态值。通俗一点理解,就是这个i的值是属于b函数的,而我们需要的i的值是实时传递进事件处理函数中的值。那么有什么方法可以实现我们的设计初衷呢?聪明的同学可能已经猜到了,那就是使用闭包。

下面我们再来看一段代码:

var a=document.getElementsByTagName("a");
function b(){


for(var i=0;i<a.length;i++){



a[i].onclick=function(j){




return function(){




alert(j);



}


}(i);

}

}

b();

执行以上代码可以发现,我们所要的功能已经实现,即点击任意a标签都会弹出该标签所在的序列号。对上述代码,相信许多同学都看过许多雷同的版本,但是为什么这样做就能实现我们需要的功能了呢,一下是个人的一点浅见,如有不当,还请不吝赐教。

对上述代码的理解,其本质就是对变量i的理解。在这段代码中,函数执行到for循环处发现了一个立即调用函数,这个时候给这个立即调用函数传递实时的i变量值,函数立即调用完成,事件处理函数也就存储了实时的i变量值。

以上所述就是本文的全部内容了,希望对大家理解js闭包能够有所帮助。

Javascript 相关文章推荐
jquery实现的超出屏幕时把固定层变为定位层的代码
Feb 23 Javascript
基于jquery点击自以外任意处,关闭自身的代码
Feb 10 Javascript
使用不同的方法结合/合并两个JS数组
Sep 18 Javascript
使用jquery提交form表单并自定义action的实现代码
May 25 Javascript
浅谈js键盘事件全面控制
Dec 01 Javascript
Vue原理剖析 实现双向绑定MVVM
May 03 Javascript
js原生实现移动端手指滑动轮播图效果的示例
Jan 02 Javascript
在vue中使用css modules替代scroped的方法
Mar 10 Javascript
vue之组件内监控$store中定义变量的变化详解
Nov 08 Javascript
在vue和element-ui的table中实现分页复选功能
Dec 04 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
Jan 08 Javascript
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
js完美实现@提到好友特效(兼容各大浏览器)
Mar 16 #Javascript
JavaScript DSL 流畅接口(使用链式调用)实例
Mar 15 #Javascript
JavaScript中的DSL元编程介绍
Mar 15 #Javascript
JavaScript中的立即执行函数表达式介绍
Mar 15 #Javascript
Javascript中的arguments与重载介绍
Mar 15 #Javascript
JavaScript中的闭包介绍
Mar 15 #Javascript
Javascript中的匿名函数与封装介绍
Mar 15 #Javascript
You might like
77A一级收信机修理记
2021/03/02 无线电
德生BCL3000的电路分析和打磨
2021/03/02 无线电
PHP中调用ASP.NET的WebService的代码
2011/04/22 PHP
PHP rmdir()函数的用法总结
2019/07/02 PHP
免费空间广告万能消除代码
2006/09/04 Javascript
关于jQuery的inArray 方法介绍
2011/10/08 Javascript
Extjs中ComboBox加载并赋初值的实现方法
2012/03/22 Javascript
子窗体与父窗体传值示例js代码
2013/08/01 Javascript
js的隐含参数(arguments,callee,caller)使用方法
2014/01/28 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
js仿腾讯QQ的web登陆界面
2016/08/19 Javascript
jQuery simpleModal插件的使用介绍
2016/08/30 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
2017/01/25 Javascript
node.js调用Chrome浏览器打开链接地址的方法
2017/05/17 Javascript
详解AngularJS ng-class样式切换
2017/06/27 Javascript
移动端效果之IndexList详解
2017/10/20 Javascript
JavaScript实现的超简单计算器功能示例
2017/12/23 Javascript
python函数局部变量用法实例分析
2015/08/04 Python
Python图像灰度变换及图像数组操作
2016/01/27 Python
python logging日志模块的详解
2017/10/29 Python
Python reduce()函数的用法小结
2017/11/15 Python
Python解决pip install时出现的Could not fetch URL问题
2019/08/01 Python
Flask框架钩子函数功能与用法分析
2019/08/02 Python
python实现计算器功能
2019/10/31 Python
基于注解实现 SpringBoot 接口防刷的方法
2021/03/02 Python
html5标记文字_动力节点Java学院整理
2017/07/11 HTML / CSS
EntityManager都有哪些方法
2013/11/01 面试题
小学教师培训感言
2014/02/11 职场文书
个性与发展自我评价
2014/02/11 职场文书
客服部工作职责范本
2014/02/14 职场文书
中青班党性分析材料
2014/02/16 职场文书
纠纷协议书
2014/04/16 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
师德师风培训感言
2015/08/03 职场文书
幼儿园教师辞职信
2019/06/21 职场文书
Mysql如何实现不存在则插入,存在则更新
2022/03/25 MySQL