javascript函数求解

hckxzy 2011-06-22 04:10:07
<body>
<div style="border: 1px solid red;">1</div>
<div style="border: 1px solid red;">2</div>
<div style="border: 1px solid red;">3</div>
<div style="border: 1px solid red;">4</div>
<div style="border: 1px solid red;">5</div>
<div style="border: 1px solid red;">6</div>
<div style="border: 1px solid red;">7</div>
</body>


var divArr = document.getElementsByTagName('DIV');
for(var i=0;i<divArr.length;i++){
divArr[i].onclick = function(){alert(i);};
}

为什么alert(i)总是同一个值,求原理说明,求解决方案?
...全文
127 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
KK3K2005 2011-06-23
  • 打赏
  • 举报
回复
查阅 js闭包 这个主题

简单说你使用的i这个变量 存在于这个内部区域中
你的onclick事件到执行的时候 才访问 i这个变量
想想看 这个时候 i都已经=divArr.length 了
hckxzy 2011-06-23
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 mstnsc5 的回复:]
楼主那种做法声明的变量i是位于全局作用域,而当Javascript解释器执行该函数时,就直接到全局作用域中
访问变量i。而变量i随着循环,变量i的值就变成了7。所以alert(i)就总是同一个值7!

至于二楼的那种做法则是在函数中声明了各自自己的变量j并且保存了自己的值,所以当Javascript解释器执行该函数时,就会到自己的函数中找自己定义的变量j的值。所以当然就正确啦!

这事实……
[/Quote]



请问为什么这样就可以了:
var divArr = document.getElementsByTagName('DIV');
for(var i=0;i<divArr.length;i++){
(new Function('divArr['+i+'].onclick = function(){alert('+i+');};'))();
}
求说明原理?
mstnsc5 2011-06-23
  • 打赏
  • 举报
回复
使用Function构造函数来创建函数,Function构造函数要求传递的参数是字符串类型。所以,如果传给Function构造函数的参数不是字符串类型,Javascript会先把这些参数都转换成字符串,然后再执行Function构造函数。如上面的代码循环第一次执行时代码会是这样:
(new Function('divArr['+0+'].onclick = function(){alert('+0+');};'))(); //因Function构造函数要求传递的是字符串类型
所以,当运行代码时,其各自有各自i的值。

不过,这种方式效率比较低。特别是用在循环中。因为每次循环都会创建一个函数对象。而使用函数直接量function(){};只会创建一个函数对象(即使是用在循环中)。
mstnsc5 2011-06-22
  • 打赏
  • 举报
回复
楼主那种做法声明的变量i是位于全局作用域,而当Javascript解释器执行该函数时,就直接到全局作用域中
访问变量i。而变量i随着循环,变量i的值就变成了7。所以alert(i)就总是同一个值7!

至于二楼的那种做法则是在函数中声明了各自自己的变量j并且保存了自己的值,所以当Javascript解释器执行该函数时,就会到自己的函数中找自己定义的变量j的值。所以当然就正确啦!

这事实上是个作用域链的问题。定义的每个函数都是个局部作用域。
燥动的心 2011-06-22
  • 打赏
  • 举报
回复
搜索闭包看一下。
hckxzy 2011-06-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 huli870715 的回复:]
(function(i){
divArr[i].onclick = function(){alert(j);};
})(i);
补充一下,这样写更符合我给你解释的原因
[/Quote]3q,3q
IcyFox 2011-06-22
  • 打赏
  • 举报
回复
(function(i){
divArr[i].onclick = function(){alert(j);};
})(i);
补充一下,这样写更符合我给你解释的原因
IcyFox 2011-06-22
  • 打赏
  • 举报
回复
原理就是js中的事件是异步的,也就是在触发那一刻才会执行事件监听函数(也就是onclic很函数)。
如楼主的写法,当onclick事件触发时,也就是当它执行的时候,for循环早就执行完了,这时候,i=divArr.length,那么楼主alert(i)的时候,总是会得到divArr.length的值。。

而当我们
(function(){
var j=i;
divArr[j].onclick = function(){alert(j);};
})();
这样写的时候,我们定义了一个闭包,把i传递进去,并执行这个闭包(它的执行是同步的)。。。。这时候,onclick绑定的是传递进去的i值,而不是循环结束的i值。。因此,就能得到正确的结果
flyerwing 2011-06-22
  • 打赏
  • 举报
回复
i引用的应该是最后一次的值也就是最大的值.
hckxzy 2011-06-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tcwsyt 的回复:]
不要重复发帖呀。。
[/Quote]

请问为什么这样就可以了:
var divArr = document.getElementsByTagName('DIV');
for(var i=0;i<divArr.length;i++){
(new Function('divArr['+i+'].onclick = function(){alert('+i+');};'))();
}
求说明原理?
sh_js 2011-06-22
  • 打赏
  • 举报
回复
好像没错啊,呵呵。学习下
hckxzy 2011-06-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tcwsyt 的回复:]
不要重复发帖呀。。
[/Quote]
不好意思,网络不好,点了两次
灬上海爽爷 2011-06-22
  • 打赏
  • 举报
回复
不要重复发帖呀。。
hckxzy 2011-06-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 guoerwei 的回复:]
for (var i=0; i<divArr.length; i++){
(function(){
var j=i;
divArr[j].onclick = function(){alert(j);};
})();
}

这样写吧
[/Quote]

说明下原理?大侠
guoerwei 2011-06-22
  • 打赏
  • 举报
回复
for (var i=0; i<divArr.length; i++){
(function(){
var j=i;
divArr[j].onclick = function(){alert(j);};
})();
}

这样写吧

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧