js闭包引起的事件注册问题
背景:闲暇时间看了几篇关于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;

看到了吧,我们通过debugger让循环在i==2时停止,然后又去控制台手动触发#anchor1和#anchor2的点击事件,结果控制台打印“anchor2”。
整个的逻辑大致是这样的:anchor.onclick一直保存着i的引用,i在循环中是一直变化的,从i=1到i=4;虽然在循环的过程中,anchor.onclick曾经保存过(注意“曾经”两字),
1,2,3这三种情况,但是i最终变成了4,所以说,无论点击哪个按钮,都会输出“anchor4”
结语:js中作用域链与闭包的知识很重要,虽然在此没有讲,其实是害怕讲不明白,反而误导了大家
js闭包引起的事件注册问题的更多相关文章
- js闭包 选择器 面向对象 事件 操作页面
闭包js函数的嵌套定义,定义在内部的函数 就称之为闭包为什么使用闭包: 1.一个函数要使用另一个函数的局部变量 2.闭包会持久化包裹自身的函数的局部变量 3.解决循环绑定 function outer ...
- Node.js 教程 05 - EventEmitter(事件监听/发射器 )
目录: 前言 Node.js事件驱动介绍 Node.js事件 注册并发射自定义Node.js事件 EventEmitter介绍 EventEmitter常用的API error事件 继承EventEm ...
- js中鼠标滚轮事件详解
js中鼠标滚轮事件详解 (以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用 ...
- js闭包和ie内存泄露原理
也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...
- JavaScript利用闭包循环绑定事件
我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用. 1.首先我们举一个简单的例子. html部分: <a href=& ...
- [JavaScript] JavaScript事件注册,事件委托,冒泡,捕获,事件流
面试题 event 事件 事件委托是什么? 如何阻止事件冒泡,阻止默认事件呢? Javascript 的事件流模型都有什么? 事件绑定和普通事件有什么区别? Event 对象 Event 对象,当事件 ...
- 关于js闭包之小问题大错误
闭包是 JavaScript 开发的一个关键方面:匿名函数可以访问父级作用域的变量. 如果闭包的作用域中保存着一个 HTML 元素,则该元素无法被销毁.(下面代码来自高程) 刚看到一个关于闭包自己没注 ...
- js调用.net后台事件,和后台调用前台等方法总结(转帖)
js调用.net后台事件,和后台调用前台等方法总结 原文来自:http://hi.baidu.com/xiaowei0705/blog/item/4d56163f5e4bf616bba16725.ht ...
- Node.js实战(九)之事件循环
Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高. Node.js 几乎每一个 API 都是支持回调函数的. Node ...
随机推荐
- C#使用protobuf
C# protobuf的使用方法 通过.proto文件导出C#支持的.cs类文件 protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.googl ...
- 用python40行代码编写的计算器
效果图 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...
- Java面向对象-方法的重载
Java面向对象-方法的重载 所谓方法的重载, 类里面有两个或者多个重名的方法,但是方法的参数个数.类型.顺序至少有一个不一样,这时候局构成方法重载: 上代码: package com.java123 ...
- Java面向对象-对象的多态性
Java面向对象-对象的多态性 Java中的多态性表现: 1,方法的重载和重写(覆盖): 2,可以用父类的引用指向子类的具体实现,而且可以随时更换为其他子类的具体实现: 我们先搞个父类Animal: ...
- zabbix监控MySQL部署实战
1.部署zabbix监控. 1.1 建用户组和用户 groupadd zabbix useradd -d /home/zabbix -g zabbix -m zabbix passwd zabbix ...
- Libevent使用例子,从简单到复杂
转载请注明出处:http://blog.csdn.net/luotuo44/article/details/39670221 本文从简单到复杂,展示如何使用libevent.网上的许多例子都是只有服务 ...
- 中国大学MOOC 设置AutoCAD的绘图环境
- shell cut 用法
cut -f 提取第几列 -d 按指定的分隔符割列 cut -f 1 xxx.txt 提取第1列 cut -f 1,3 xxx.txt 提取第1,3列 cut -d ":&qu ...
- 4、MemorySubSystem
1.概述 S3C6410X存储器子系统包括7个存储器控制器,SROM控制器,两个OneNAND控制器,一个NAND Flash控制器,一个CF控制器,一个DRAM控制器.静态存储器控制器,oneNAN ...
- SpringMVC——映射请求参数
Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中. @PathVariable @RequestParam @RequestHeader 等) Sprin ...