分析js闭包引起的事件注册问题


Posted in Javascript onMarch 29, 2016

背景:闲暇时间看了几篇关于js作用域链与闭包的文章,偶然又看到了之前遇到的一个问题,就是在for循环中为dom节点注册事件驱动,具体见下面代码:

<!DOCTYPE html>
<html>
 <head>
 <title>js闭包</title>
 <meta charset="utf-8" />
 </head>
 <body>
 <button id="anchor1">1</button>
 <button id="anchor2">2</button>
 <button id="anchor3">3</button>
 <script type="text/javascript" src="jquery-1.12.1.js"></script>
 <script type="text/javascript">
  function pageLoad(){
  for (var i = 1; i <=3; i++) { 
   var anchor = document.getElementById("anchor" + i);
   anchor.onclick = function () {
   console.log("anchor"+i);
   } 
  } 
  } 
  window.onload = pageLoad; 
 </script>
 </body>
</html>

按照正常的想法,结果应该是点击3个按钮分别提示“anchor1”、“anchor2”、“anchor3”;期初我也是这么认为的,但是结果却是不管点击哪个按钮,都会提示“anchor4”。

这是为什么呢?不要着急,待我们慢慢分析,这里面包含js作用域链与闭包的知识,在这里我就不详细介绍了。

首先我们看这个anchor.onclick,这是什么?这是dom0级事件处理程序啊,废话,我也知道,博主是蛇精病吗*************不要吵了,我想说的是这个anchor.onclick

是一个事件处理程序的声明,就像var name="小明"一样,这是声明了,但是还没有执行,这就是关键,我们将上面的js代码修改一下再来看看:

function pageLoad(){
  for (var i = 1; i <=3; i++) { 
  var anchor = document.getElementById("anchor" + i);
   anchor.onclick = function () {
   console.log("anchor"+i);
   } 
   if(i==2){
   debugger;//我们在这里debugger一下,然后在控制台手动触发#anchor1和#anchor2的点击事件
   }
  } 
 } 
 window.onload = pageLoad;

分析js闭包引起的事件注册问题

看到了吧,我们通过debugger让循环在i==2时停止,然后又去控制台手动触发#anchor1和#anchor2的点击事件,结果控制台打印“anchor2”。

整个的逻辑大致是这样的:anchor.onclick一直保存着i的引用,i在循环中是一直变化的,从i=1到i=4;虽然在循环的过程中,anchor.onclick曾经保存过(注意“曾经”两字),

1,2,3这三种情况,但是i最终变成了4,所以说,无论点击哪个按钮,都会输出“anchor4”

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JS获取月的最后一天与JS得到一个月份最大天数的实例代码
Dec 16 Javascript
Javascript中String的常用方法实例分析
Jun 13 Javascript
js滑动提示效果代码分享
Mar 10 Javascript
jQuery解析XML 详解及方法总结
Sep 28 Javascript
JavaScript数组的5种迭代方法
Sep 29 Javascript
js中的闭包学习心得
Feb 06 Javascript
使用vue制作探探滑动堆叠组件的实例代码
Mar 07 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
Oct 12 Javascript
详解JavaScript中typeof与instanceof用法
Oct 24 Javascript
微信小程序用户拒绝授权的处理方法详解
Sep 20 Javascript
JavaScript链式调用原理与实现方法详解
May 16 Javascript
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 Vue.js
使用postMesssage()实现iframe跨域页面间的信息传递
Mar 29 #Javascript
Angularjs实现多个页面共享数据的方式
Mar 29 #Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
Mar 29 #Javascript
JavaScript面向对象程序设计教程
Mar 29 #Javascript
jQuery实现图片加载完成后改变图片大小的方法
Mar 29 #Javascript
Web前端开发工具——bower依赖包管理工具
Mar 29 #Javascript
Jquery操作cookie记住用户名
Mar 29 #Javascript
You might like
PHP 面向对象 final类与final方法
2010/05/05 PHP
Windows下利用Gvim写PHP产生中文乱码问题解决方法
2011/04/20 PHP
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
php中拷贝构造函数、赋值运算符重载
2012/07/25 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
2016/08/17 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
php-7.3.6 编译安装过程
2020/02/11 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
DLL+ ActiveX控件+WEB页面调用例子
2010/08/07 Javascript
基于javascript 闭包基础分享
2013/07/10 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
超实用的javascript时间处理总结
2016/08/16 Javascript
最全面的百度地图JavaScript离线版开发
2016/09/10 Javascript
用Vue-cli搭建的项目中引入css报错的原因分析
2017/07/20 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
JS库中的Particles.js在vue上的运用案例分析
2017/09/13 Javascript
详解vuex中mapState,mapGetters,mapMutations,mapActions的作用
2018/04/13 Javascript
Vue-cli配置打包文件本地使用的教程图解
2018/08/02 Javascript
JavaScript中toLocaleString()和toString()的区别实例分析
2018/08/14 Javascript
React中使用UEditor百度富文本的方法
2018/08/22 Javascript
详解vue为什么要求组件模板只能有一个根元素
2019/07/22 Javascript
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
antd-mobile ListView长列表的数据更新遇到的坑
2020/04/08 Javascript
Vue中watch、computed、updated三者的区别及用法
2020/07/27 Javascript
vue 使用lodash实现对象数组深拷贝操作
2020/09/10 Javascript
[54:15]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第二场2月1日
2021/03/11 DOTA
linux中如何使用python3获取ip地址
2019/07/15 Python
python plotly绘制直方图实例详解
2019/07/22 Python
PyCharm2018 安装及破解方法实现步骤
2019/09/09 Python
简单了解python中的与或非运算
2019/09/18 Python
Matplotlib.pyplot 三维绘图的实现示例
2020/07/28 Python
Python用摘要算法生成token及检验token的示例代码
2020/12/01 Python
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
简述DNS进行域名解析的过程
2013/12/02 面试题
研讨会致辞
2015/07/31 职场文书