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 相关文章推荐
基于jQuery的ajax功能实现web service的json转化
Aug 29 Javascript
jquery 简单导航实现代码
Sep 11 Javascript
获取服务器传来的数据 用JS去空格的正则表达式
Mar 26 Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
Apr 07 Javascript
JS限制Textarea文本域字符个数的具体实现
Aug 02 Javascript
js数组循环遍历数组内所有元素的方法
Jan 18 Javascript
常用的JavaScript模板引擎介绍
Feb 28 Javascript
JS实用的动画弹出层效果实例
May 05 Javascript
jQuery实现可高亮显示的二级CSS菜单效果
Sep 01 Javascript
微信小程序 获取微信OpenId详解及实例代码
Oct 31 Javascript
原生js jquery ajax请求以及jsonp的调用方法
Aug 04 jQuery
vue-router命名路由和编程式路由传参讲解
Jan 19 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
世界第一个无线广播电台 KDKA
2021/03/01 无线电
基于swoole实现多人聊天室
2018/06/14 PHP
取得父标签
2006/11/14 Javascript
jQuery实现流动虚线框的方法
2015/01/29 Javascript
jQuery密码强度检测插件passwordStrength用法实例分析
2015/10/30 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
2016/01/12 Javascript
浅谈jquery高级方法描述与应用
2016/10/04 Javascript
微信小程序 122100版本更新问题解决方案
2016/12/22 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
vue实现循环切换动画
2018/10/17 Javascript
vue项目中实现缓存的最佳方案详解
2019/07/11 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
2020/07/22 Javascript
详解React的回调渲染模式
2020/09/10 Javascript
基于循环神经网络(RNN)的古诗生成器
2018/03/26 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
分享vim python缩进等一些配置
2018/07/02 Python
解决PyCharm import torch包失败的问题
2018/10/13 Python
为什么Python中没有&quot;a++&quot;这种写法
2018/11/27 Python
Python read函数按字节(字符)读取文件的实现
2019/07/03 Python
Django DRF APIView源码运行流程详解
2020/08/17 Python
利用Python的folium包绘制城市道路图的实现示例
2020/08/24 Python
详解基于Scrapy的IP代理池搭建
2020/09/29 Python
5款实用的python 工具推荐
2020/10/13 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
英国花园、DIY、电器和家居用品商店:Robert Dyas
2019/03/18 全球购物
Nordgreen台湾官网:极简北欧设计手表
2019/08/21 全球购物
ECCO俄罗斯官网:北欧丹麦鞋履及皮具品牌
2020/06/26 全球购物
一道写SQL的面试题和答案
2013/11/19 面试题
十佳标兵事迹材料
2014/08/18 职场文书
个人作风建设总结
2014/10/23 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
聘任书的格式及模板
2019/10/28 职场文书
Python破解极验滑动验证码详细步骤
2021/05/21 Python
javascript之Object.assign()的痛点分析
2022/03/03 Javascript