JS 闭包问题- for循环取 i

来源:互联网 发布:阿里云服务器租用合同 编辑:程序博客网 时间:2024/06/05 21:52

问题描述:

<!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);
}

0 0
原创粉丝点击