javascript闭包传参和事件的循环绑定示例探讨


Posted in Javascript onApril 17, 2014

今天看到一个javascript的题目,按常理循环绑定事件,但是得到的结果却不是想要的。

<a href="#">text</a> 
<br> 
<a href="#">link</a> 
<script> 
var as = document.getElementsByTagName('a'); 
for ( var i = as.length; i--; ) { 
as[i].onclick = function() { 
alert(i); 
return false; 
} 
} 
</script>

1.这个代码点击链接弹出的i都是-1,这是为啥呢?

简单来说就是函数变量作用域问题,如果把function() { alert(i); return false; } 当做一个函数 a();a()内部未定义变量i,但是内部使用了,于是向外查找,找到for循环里定义的i,点击事件是for循环完毕后才开始执行的,执行完毕后i的值已经变成-1;所以每次弹出的都是-1;

2. 2个参数的for循环也不常见!疑惑?

for(语句1,语句2,语句3){

//todo

}

a.for循环条件

通常说语句1、语句2、语句3都是可选的。

b.语句 2:

通常语句 2 用于评估初始变量的条件。

语句 2 同样是可选的。

如果语句 2 返回 true,则循环再次开始,如果返回 false,则循环将结束。

提示:如果您省略了语句 2,那么必须在循环内提供 break。否则循环就无法停下来。这样有可能令浏览器崩溃。

c.关于 i--判断:

判断i--true /false的时候是先判断i再运算i--的。进入最后一次判断 i--的时候其实判断 i==0的时候,判断后又执行了一次i--,for循环终止, 于是i的值变成了-1;

var i = 1;

!!i--;//ture

解决方法:

var as = document.getElementsByTagName('a'); 
for ( var i = as.length; i--; ) { 
(function(i){ 
as[i].onclick = function() { 
alert(i); 
return false; 
} 
})(i) 
}

或者:
var as = document.getElementsByTagName('a'); 
for ( var i = as.length; i--; ) { 
var a = function(i){ 
as[i].onclick = function() { 
alert(i); 
return false; 
} 
} 
a(i); 
}

其他网友7中解决方法demo:
<html > 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>闭包演示</title> 
<script type="text/javascript"> function init() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
pAry[i].onclick = function() { 
alert(i); 
} 
} 
} 
</script> 
</head> 
<body onload="init();"> 
<p>产品一</p> 
<p>产品二</p> 
<p>产品三</p> 
<p>产品四</p> 
<p>产品五</p> 
</body> 
</html>

1、将变量 i 保存给在每个段落对象(p)上
function init() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
pAry[i].i = i; 
pAry[i].onclick = function() { 
alert(this.i); 
} 
} 
}

2、将变量 i 保存在匿名函数自身
function init2() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
(pAry[i].onclick = function() { 
alert(arguments.callee.i); 
}).i = i; 
} 
}

3、加一层闭包,i以函数参数形式传递给内层函数
function init3() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
(function(arg){ 
pAry[i].onclick = function() { 
alert(arg); 
}; 
})(i);//调用时参数 
} 
}

4、加一层闭包,i以局部变量形式传递给内存函数
function init4() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
(function () { 
var temp = i;//调用时局部变量 
pAry[i].onclick = function() { 
alert(temp); 
} 
})(); 
} 
}

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
function init5() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
pAry[i].onclick = function(arg) { 
return function() {//返回一个函数 
alert(arg); 
} 
}(i); 
} 
}

6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
function init6() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例 
} 
}

7、用Function实现,注意与6的区别
function init7() { 
var pAry = document.getElementsByTagName("p"); 
for( var i=0; i<pAry.length; i++ ) { 
pAry[i].onclick = Function('alert('+i+')') 
} 
}

总结完成,欢迎拍砖!
Javascript 相关文章推荐
用js计算页面执行时间的函数
Dec 07 Javascript
如何让动态插入的javascript脚本代码跑起来。
Jan 09 Javascript
Prototype最新版(1.5 rc2)使用指南(1)
Jan 10 Javascript
关于document.cookie的使用javascript
Apr 11 Javascript
JavaScript学习笔记(一) js基本语法
Oct 25 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
jQuery中fadeOut()方法用法实例
Dec 24 Javascript
angularjs表格ng-table使用备忘录
Mar 09 Javascript
vue使用Proxy实现双向绑定的方法示例
Mar 20 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
Sep 26 Javascript
JavaScript中的null和undefined用法解析
Sep 30 Javascript
vue实现扫码功能
Jan 17 Javascript
window.location不跳转的问题解决方法
Apr 17 #Javascript
JavaScript避免代码的重复执行经验技巧分享
Apr 17 #Javascript
js中的cookie的读写操作示例详解
Apr 17 #Javascript
巧用replace将文字表情替换为图片
Apr 17 #Javascript
JavaScript事件委托的技术原理探讨示例
Apr 17 #Javascript
JS实现div居中示例
Apr 17 #Javascript
淘宝网提供的国内NPM镜像简介和使用方法
Apr 17 #Javascript
You might like
一个简洁的PHP可逆加密函数(分享)
2013/06/06 PHP
一个漂亮的php验证码类(分享)
2013/08/06 PHP
php对csv文件的读取,写入,输出下载操作详解
2013/08/10 PHP
PHP 只允许指定IP访问(允许*号通配符过滤IP)
2014/07/08 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
2017/08/01 PHP
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
2013/01/09 Javascript
JS文本框不能输入空格验证方法
2013/03/19 Javascript
浅谈关于JavaScript API设计的一些建议和准则
2015/06/24 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
详解Angular开发中的登陆与身份验证
2016/07/27 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
React如何将组件渲染到指定DOM节点详解
2017/09/08 Javascript
微信小程序实现漂亮的弹窗效果
2020/05/26 Javascript
vue 监听屏幕高度的实例
2018/09/05 Javascript
React注册倒计时功能的实现
2018/09/06 Javascript
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
python黑魔法之参数传递
2016/02/12 Python
一文带你了解Python中的字符串是什么
2018/11/20 Python
Python中常用的内置方法
2019/01/28 Python
Python configparser模块常用方法解析
2020/05/22 Python
Python3交互式shell ipython3安装及使用详解
2020/07/11 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
中式面点餐厅创业计划书
2014/01/29 职场文书
优秀毕业生自我鉴定
2014/02/11 职场文书
新教师岗前培训方案
2014/06/05 职场文书
车间安全生产标语
2014/06/06 职场文书
校长四风对照检查材料
2014/09/27 职场文书
校园新闻广播稿5篇
2014/10/10 职场文书
运动会通讯稿300字
2015/07/20 职场文书
《孙子兵法》:欲成大事者,需读懂这些致胜策略
2019/08/23 职场文书
Django一小时写出账号密码管理系统
2021/04/29 Python
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL
weblogic服务建立数据源连接测试更新mysql驱动包的问题及解决方法
2022/01/22 MySQL
直播实况, OMG破敌三路五十分钟大战神技局摩托车
2022/04/01 DOTA
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis