JavaScript中循环给元素添加onclick事件局部变量的值均相同的怪异现象

恋喵大鲤鱼
领域专家: C/C++技术领域
2016-09-02 10:19:57
请参考如下代码,为何任意点击任意一个span弹出的都是2?

<!doctype html>

<html>
<head>
</head>
<body>
<div id="testDiv">
<span>lvlv0</span>
<span>lvlv1</span>
</div>
</body>
</html>
<script>
function closure(){
var localVar=1;
var div=document.getElementById("testDiv");
var spanArray=div.getElementsByTagName("span");
for(var i=0;i<spanArray.length;++i){
spanArray[i].onclick=function(){
var nestedLocalVar=i;
alert(nestedLocalVar);
};
}
//alert(nestedLocalVar);
}
closure();
</script>


我知道这个存在闭包和作用域链的问题,但是如果因作用域链的话,但是nestedLocalVar是事件函数中的局部变量,为何还是指向了最终的变量i呢?
...全文
442 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jio可 2016-09-02
  • 打赏
  • 举报
回复
点击的时候循环已经执行完了,但最后还要去执行i++ ,i就等于2了,你点击的时候用的还是上面个声明的i,它已经是2了。
  • 打赏
  • 举报
回复
引用 5 楼 K346K346 的回复:
嗯嗯,知道这两个解决办法,但是出现上面的问题的原因是什么呢?
var nestedLocalVar=i;因为你的i一直在变
恋喵大鲤鱼 2016-09-02
  • 打赏
  • 举报
回复
引用 楼主 K346K346 的回复:
请参考如下代码,为何任意点击任意一个span弹出的都是2?

<!doctype html>

<html>
	<head>
	</head>
	<body>
	<div id="testDiv">
		<span>lvlv0</span>
		<span>lvlv1</span>
	</div>
	</body>
</html>
<script>
function closure(){
	var localVar=1;
	var div=document.getElementById("testDiv");
	var spanArray=div.getElementsByTagName("span");
	for(var i=0;i<spanArray.length;++i){
		spanArray[i].onclick=function(){
			var nestedLocalVar=i;
			alert(nestedLocalVar);
		};
	}
	//alert(nestedLocalVar);
}
closure();
</script>
我知道这个存在闭包和作用域链的问题,但是如果因作用域链的话,但是nestedLocalVar是事件函数中的局部变量,为何还是指向了最终的变量i呢?
嗯嗯,知道这两个解决办法,但是出现上面的问题的原因是什么呢?
恋喵大鲤鱼 2016-09-02
  • 打赏
  • 举报
回复
引用 楼主 K346K346 的回复:
请参考如下代码,为何任意点击任意一个span弹出的都是2?

<!doctype html>

<html>
	<head>
	</head>
	<body>
	<div id="testDiv">
		<span>lvlv0</span>
		<span>lvlv1</span>
	</div>
	</body>
</html>
<script>
function closure(){
	var localVar=1;
	var div=document.getElementById("testDiv");
	var spanArray=div.getElementsByTagName("span");
	for(var i=0;i<spanArray.length;++i){
		spanArray[i].onclick=function(){
			var nestedLocalVar=i;
			alert(nestedLocalVar);
		};
	}
	//alert(nestedLocalVar);
}
closure();
</script>
我知道这个存在闭包和作用域链的问题,但是如果因作用域链的话,但是nestedLocalVar是事件函数中的局部变量,为何还是指向了最终的变量i呢?
{在事件响应的时候,已经指向了循环的最后值},为什么会指向循环变量 i 的最后值呢?
  • 打赏
  • 举报
回复
纯js就用匿名闭包函数,特点定义完立即执行

function closure(){
    var localVar=1;
    var div=document.getElementById("testDiv");
    var spanArray=div.getElementsByTagName("span");
    for(var i=0;i<spanArray.length;++i){
    	(function (x) {
    		spanArray[x].onclick = function () { 
    		alert(x);
    		}
    	})(i);
    }
    //alert(nestedLocalVar);
}
closure();
  • 打赏
  • 举报
回复

    for (var i = 0; i < spanArray.length; ++i) {
        spanArray[i].onclick = (function (i) {
            return function () { alert(i); }
        })(i);
    }
  • 打赏
  • 举报
回复
在事件响应的时候,已经指向了循环的最后值 你可以闭包实现,或者 简单的循环时赋给span的一个属性上,点击时调取对象的属性值
恋喵大鲤鱼 2016-09-02
  • 打赏
  • 举报
回复
引用 5 楼 K346K346 的回复:
[quote=引用 楼主 K346K346 的回复:] 请参考如下代码,为何任意点击任意一个span弹出的都是2?

<!doctype html>

<html>
	<head>
	</head>
	<body>
	<div id="testDiv">
		<span>lvlv0</span>
		<span>lvlv1</span>
	</div>
	</body>
</html>
<script>
function closure(){
	var localVar=1;
	var div=document.getElementById("testDiv");
	var spanArray=div.getElementsByTagName("span");
	for(var i=0;i<spanArray.length;++i){
		spanArray[i].onclick=function(){
			var nestedLocalVar=i;
			alert(nestedLocalVar);
		};
	}
	//alert(nestedLocalVar);
}
closure();
</script>
我知道这个存在闭包和作用域链的问题,但是如果因作用域链的话,但是nestedLocalVar是事件函数中的局部变量,为何还是指向了最终的变量i呢?
嗯嗯,知道这两个解决办法,但是出现上面的问题的原因是什么呢?[/quote]我想问的是为什么nestedLocalVar指向 i 呢?

87,990

社区成员

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

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