问题描述:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
functiononMyLoad(){
var arr = document.getElementsByTagName("p");
for(var i = 0; i < arr.length;i++){
arr[i].onclick = function(){//匿名函数作为回调函数
alert(i); /发现i是未知的,沿着作用域查找i,但是i是经过for循环后得到的值,i=4
}
}
}
</script>
</head>
<body onload="onMyLoad()">
<p>
产品一
</p>
<p>
产品二
</p>
<p>
产品三
</p>
<p>
产品四
</p>
<p>
产品五
</p>
</body>
</html>原因分析:
当for循环执行完毕后,i变量被垃圾回收,接着执行click函数的时候,因为内部没有i变量所以会去父级作用域去找,那时for循环已经执行完成,所以只会输出6
解决办法1:
/*解决思路:增加若干个对应的闭包域空间(这里采用的是匿名函数),专门用来存储原先需要引用的内容(下标),不过只限于基本类型(基本类型值传递,对象类型引用传递)
*/
for(var i = 0; i<arr.length;i++){
(function(){
var temp = i;
arr[i].onclick = function () {
alert(temp);
}
})();
}
解决办法二
/*
解决思路
:
与解决办法一有点相似但却有点不太相似
.
相似点
:
同样是增加若干个对应的闭包域空间用来存储下标
不同点
:
解决办法一是在新增的匿名闭包空间内完成事件的绑定
,
而此例是将事件绑定在新增的匿名函数返回的函数上
此时绑定的函数中的
functionscope中的closure对象的引用arg是指向将其返回的匿名函数的私有变量arg
*/
for(var i = 0; i<arr.length;i++){
arr[i].onclick = (
function(arg){
returnfunction()
{
alert(arg);
}
})(i);
}