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 相关文章推荐
document.documentElement &amp;&amp; document.documentElement.scrollTop
Dec 01 Javascript
JS定时关闭窗口的实例
May 22 Javascript
js实现按钮加背景图片常用方法
Nov 01 Javascript
javascript实现的右下角弹窗实例
Apr 24 Javascript
JavaScript检测鼠标移动方向的方法
May 22 Javascript
JS中的THIS和WINDOW.EVENT.SRCELEMENT详解
May 25 Javascript
Vue2.x中的Render函数详解
May 30 Javascript
简单理解Vue中的nextTick方法
Jan 30 Javascript
Vue加载组件、动态加载组件的几种方式
Aug 31 Javascript
jQuery实现的分页插件完整示例
May 26 jQuery
vue npm install 安装某个指定的版本操作
Aug 11 Javascript
vue中使用router全局守卫实现页面拦截的示例
Oct 23 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
Syphon 秘笈
2021/03/03 冲泡冲煮
PHP如何透过ODBC来存取数据库
2006/10/09 PHP
PHP中的函数-- foreach()的用法详解
2013/06/24 PHP
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
2013/08/10 PHP
php的ajax简单实例
2014/02/27 PHP
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
2016/03/03 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
jquery之Document元素选择器篇
2008/08/14 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
深入理解基于vue-cli的vuex配置
2017/07/24 Javascript
详解使用angular的HttpClient搭配rxjs
2017/09/01 Javascript
vue父组件中获取子组件中的数据(实例讲解)
2017/09/27 Javascript
vue一个页面实现音乐播放器的示例
2018/02/06 Javascript
vue路由中前进后退的一些事儿
2019/05/18 Javascript
ReactRouter的实现方法
2021/01/25 Javascript
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
[01:09:01]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第一场 10.28
2020/10/28 DOTA
python在windows下实现备份程序实例
2014/07/04 Python
Python3写入文件常用方法实例分析
2015/05/22 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
python几种常用功能实现代码实例
2019/12/25 Python
Jupyter Notebook 实现正常显示中文和负号
2020/04/24 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
Sephora丝芙兰菲律宾官方网站:购买化妆品和护肤品
2017/04/05 全球购物
财务管理个人自荐书范文
2013/11/24 职场文书
超市商业计划书
2014/05/04 职场文书
中国梦团日活动总结
2014/07/07 职场文书
学习“七一”讲话精神体会
2014/07/08 职场文书
乡党委干部党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
事业单位聘任报告
2015/03/02 职场文书
保研专家推荐信范文
2015/03/25 职场文书
导游带团欢迎词
2015/09/30 职场文书
2015年美容师个人工作总结
2015/10/14 职场文书