代码如下:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Untitled</title>
<script>
    function func() {
      var i;
      for (i = 1; i <= 4; i++) {
      var el = document.getElementById('closureExample' + i);
      el.onclick = function() { alert(i) };
     
  }
} window.onload = function() {
    func();
}
</script>
</head><body>
<a href="#" id="closureExample1">例子1</a>
<a href="#" id="closureExample2">例子2</a>
<a href="#" id="closureExample3">例子3</a>
<a href="#" id="closureExample4">例子3</a>
</body>
</html>
我的本意:    
    是想单击例子1,例子2,例子3,例子4的时候,分别弹出1,2,3,4的,但是结果却发现弹出的都是5
我估计如下:
    绑定的时候,是动态绑定的,只不过将事件绑定到了元素身上而已,但是参数却是在变的
当i==4的时候,由于运行了i++所以最终成了5  显示出来的结果当然是5了  
我的猜想:
    是不是在绑定的时候先运行一下click事件就可以解决这个问题呢?
现在寻求如何解决这一问题

解决方案 »

  1.   

    el.onclick = function() { alert(i) };
    ==>
    el.onclick = (function(n) {
      return function() {alert(n);}
    })(i)
      

  2.   

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    <head>
        <title>Untitled</title>
        <script>
        function func() {
              var i;
              for (i = 1; i <= 4; i++) {
     document.getElementById("closureExample"+i).onclick = (function(n) {
        return function() {alert(n);}
    })(i)         
           }
        }    window.onload = function() {
            func();
        }
        </script>    
    </head><body>
    <a href="#" id="closureExample1">例子1</a>
    <a href="#" id="closureExample2">例子2</a>
    <a href="#" id="closureExample3">例子3</a>
    <a href="#" id="closureExample4">例子3</a>
    </body>
    </html>
      

  3.   

    cj锅正解。
    i的作用域是整个func函数。
    在onclick的时候func函数内部的i已经是5了。
    用cj锅那种形式,在i还是1/2/3/4/5的时候,分别传入匿名函数中,在匿名函数的环境中,存储了i在执行函数时的值,也就是分别是1 2 3 4 5
      

  4.   

    就是闭包
    函数绑定的是变量i
    但是循环结束之后i的值已经变了
    这个时候你触发事件调用的i就是最大的值了
    关于闭包 http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html 是最好的文档。
      

  5.   


                   function func() {
    for (var i = 1; i <= 4; i++) {
    var el = document.getElementById('closureExample' + i);
    el.setAttribute('index', i);
    el.onclick = function() {
    alert(this.getAttribute('index'));
    };
    }
    }
      

  6.   

    也开始使用 即时执行 的办法。  function func() {
              for (i = 1; i <= 4; i++) {
              var el = document.getElementById('closureExample' + i);
     
      (function(){
       var ii = i;
       el.onclick = function(){ alert(ii);};
       
       })();
             
             
          }
        }
      

  7.   

    function func() {
         for (var i = 1; i <= 4; i++) {
              with ({i:i}) { 
                   var el = document.getElementById('closureExample' + i);
                   el.onclick = function() { alert(i) };
              }
         }
    }
      

  8.   

    最简单的方法就是用 jquery 之类框架的 each , 自已写一个 each 也很容易我自已实现了这种方式
    new Array().fillRange(1,4).each(function(i){
        document.getElementById("closureExample"+i).onclick = function(n) {
                  alert(i)
         }})
      

  9.   

     所谓闭包是跟函数定义的上下文(context)和作用域(scope)共同决定的。     function func() {
              var i;
              for (i = 1; i <= 4; i++) {
                var el = document.getElementById('closureExample' + i);
                el.onclick = function() { alert(i) }; //这个函数的上下文是func函数,这样onclick能访问func函数定义的i变量,他没有绑定那个值,只是能访问上下文的变量,这样最终执行onclick时i已经在这个上下文中有固定值5,所以全部onclick都显示5       
             }
          }
      

  10.   

    el.onclick = function() { alert(i) };
    这是活的
    el.onclick = (function(n) {
      return function() {alert(n);}
    })(i)
    这是死的这样理解就直观了
      

  11.   

    el.onclick = function() { alert(i) };
    这样只创建了一层闭包,alert显示的变量i就是外层函数里的局部变量,循环结束之后,他的值被改变成5了,所以,触发点击事件的时候引用的还是这个变量,其值是5
    el.onclick = (function(n) {
      return function() {alert(n);}
    })(i)
    这种 做法创建了两层闭包,alert显示的变量在匿名函数里的参数,他是以参数的形式传递进来的,后面也没有操作改变这个值,所以一次点击会有不同的值,实际上与上面不同的是,alert显示的i引用了不同的变量,而上面的例子却引用了相同的变量