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 相关文章推荐
JavaScript传递变量: 值传递?引用传递?
Feb 22 Javascript
jQuery表格插件ParamQuery简单使用方法示例
Dec 05 Javascript
javascript下拉框选项单击事件的例子分享
Mar 04 Javascript
在JavaScript中访问字符串的子串
Jul 07 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
May 21 Javascript
jQuery ajax中使用confirm,确认是否删除的简单实例
Jun 17 Javascript
JavaScript实现自动切换图片代码
Oct 11 Javascript
详解JavaScript模块化开发
Dec 04 Javascript
vue项目打包后上传至GitHub并实现github-pages的预览
May 06 Javascript
Vue路由前后端设计总结
Aug 06 Javascript
Vue中的循环及修改差值表达式的方法
Aug 29 Javascript
Node.js path模块,获取文件后缀名操作
Nov 07 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中将网址转换为超链接的函数
2011/09/02 PHP
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
PHP实现对xml的增删改查操作案例分析
2017/05/19 PHP
Laravel中的Blade模板引擎示例详解
2017/10/10 PHP
php封装的page分页类完整实例代码
2020/02/01 PHP
用js实现的仿sohu博客更换页面风格(简单版)
2007/03/22 Javascript
javascript 全等号运算符使用说明
2010/05/31 Javascript
JavaScript获取表单内所有元素值的方法
2015/04/02 Javascript
js中的内部属性与delete操作符介绍
2015/08/10 Javascript
JS实现Fisheye效果动感放大菜单代码
2015/10/21 Javascript
jQuery获取多种input值的简单实现方法
2016/06/20 Javascript
用jQuery向div中添加Html文本内容的简单实现
2016/07/13 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
javascript标准库(js的标准内置对象)总结
2018/05/26 Javascript
浅谈javascript中的prototype和__proto__的理解
2019/04/07 Javascript
JS模拟浏览器实现全局搜索功能
2019/09/11 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
[02:54]DOTA2亚洲邀请赛 VG战队出场宣传片
2015/02/07 DOTA
[03:08]TI9战队档案 - Vici Gaming
2019/08/20 DOTA
Python正则表达式完全指南
2017/05/25 Python
Python实现发送与接收邮件的方法详解
2018/03/28 Python
Pandas:DataFrame对象的基础操作方法
2018/06/07 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
2018/06/28 Python
Python对接六大主流数据库(只需三步)
2019/07/31 Python
tensorflow 2.0模式下训练的模型转成 tf1.x 版本的pb模型实例
2020/06/22 Python
python绘制趋势图的示例
2020/09/17 Python
通信专业个人自我鉴定
2013/10/21 职场文书
应届大学生求职信
2013/12/01 职场文书
建筑设计学生的自我评价
2014/01/16 职场文书
信访维稳工作汇报
2014/10/27 职场文书
幼儿园教师求职信
2015/03/20 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
导游词之山东孔庙
2019/11/04 职场文书
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
浅析Django接口版本控制
2021/06/26 Python
JS实现刷新网页后之前浏览位置保持不变示例详解
2022/08/14 Javascript