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输出列表实现代码
Sep 12 Javascript
Jquery ajaxsubmit上传图片实现代码
Nov 04 Javascript
jquery写个checkbox——类似邮箱全选功能
Mar 19 Javascript
jquery实现点击消失的代码
Mar 03 Javascript
jquery基础教程之数组使用详解
Mar 10 Javascript
一个Action如何调用两个不同的方法
May 22 Javascript
jquery文档操作wrap()方法实例简述
Jan 10 Javascript
JS使用post提交的两种方式
Dec 03 Javascript
深入浅析AngularJS中的module(模块)
Jan 04 Javascript
js实现炫酷的左右轮播图
Jan 18 Javascript
javascript面向对象三大特征之继承实例详解
Jul 24 Javascript
解决layui的使用以及针对select、radio等表单组件不显示的问题
Sep 05 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
zf框架的db类select查询器join链表使用示例(zend框架)
2014/03/14 PHP
PHP把网页保存为word文件的三种方法
2014/04/01 PHP
Codeigniter操作数据库表的优化写法总结
2014/06/12 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
jqplot通过ajax动态画折线图的方法及思路
2013/12/08 Javascript
JQuery datepicker 用法详解
2015/12/25 Javascript
JS自定义混合Mixin函数示例
2016/11/26 Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
2018/07/03 Javascript
react实现换肤功能的示例代码
2018/08/14 Javascript
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
编写更好的JavaScript条件式和匹配条件的技巧(小结)
2019/06/27 Javascript
解决Layui当中的导航条动态添加后渲染失败的问题
2019/09/25 Javascript
vscode 配置vue+vetur+eslint+prettier自动格式化功能
2020/03/23 Javascript
vue element和nuxt的使用技巧分享
2021/01/14 Vue.js
python读取浮点数和读取文本文件示例
2014/05/06 Python
在Python中操作字典之update()方法的使用
2015/05/22 Python
教你用Type Hint提高Python程序开发效率
2016/08/08 Python
Python编程深度学习计算库之numpy
2018/12/28 Python
对Python的多进程锁的使用方法详解
2019/02/18 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
2019/07/18 Python
Python图片的横坐标汉字实例
2019/12/04 Python
python读取csv文件指定行的2种方法详解
2020/02/13 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
2021/02/22 Python
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
什么是lambda函数
2013/09/17 面试题
应届毕业生求职信
2013/11/30 职场文书
民生工作实施方案
2014/05/31 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
家长对孩子的寄语
2015/02/26 职场文书
2015年高校辅导员工作总结
2015/04/20 职场文书
2015年老干部工作总结
2015/04/23 职场文书
2016年教师节贺卡寄语
2015/12/04 职场文书
攻击最高的10只幽灵系神奇宝贝,坚盾剑怪排第一,第五最为可怕
2022/03/18 日漫
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle
Python使用pandas导入csv文件内容的示例代码
2022/12/24 Python