下面这一段代码输出的全是4,这是什么问题啊??
var a=[1,2,3];
for(i in a)
{
  a[i]=function (){
    return i*i;
  }
}
alert(a[0]());
alert(a[1]());
alert(a[2]());

解决方案 »

  1.   


    var a=[1,2,3];
    for(i in a)
    {
      a[i]=(function (i){
        return function(){return i*i;}
      })(i)
    }
    alert(a[0]());
    alert(a[1]());
    alert(a[2]());
      

  2.   

    故计你是想得到a中每个元素相乘的结果,即1,4,9.
    如果是这样的话
    var a=[1,2,3];
    var n=0;
    var b=[];
    for(i in a)
    {  b[n]=(function (i){
        return function(){return a[i]*a[i];}
      })(i)
      n++;
    }
    alert(b[0]());
    alert(b[1]());
    alert(b[2]());
      

  3.   

    个人理解
    没有闭包,for 循环结束后,内存中只保留了 i=2
    所以后面输出全是4
      

  4.   

    很显然是先执行for循环体,然后再执行那个function有这种想象,高人指点
    <script>
    var a=[1,2,3];
    for(i in a)
    {
    alert("for_i = "+i);
      a[i]=function (){ 
      alert("fun_i = "+i);
      return i*i; }
    }
    alert(a[0]());
    alert(a[1]());
    alert(a[2]());</script>
      

  5.   

    当然是闭包。什么是闭包?就是一个函数外加这个函数的生存环境,合起来成为闭包。
    回顾上例,
    for(i in a)
    {
      a[i]=function (){
        return i*i;
      }
    }
    你每次定义一个匿名函数,都有一个独特的生存环境:i,此i不是来自于函数内部,而是函数外部的循环体。可是循环体的这个i的变量,在每次循环后,都指向同一个i,所以,你的所有函数所引用的i是同一个i。同时,由于i是循环体内部的变量,按理,在循环结束后,会被系统释放,可是由于参与了别的函数的闭包,导致它必须存在于内存里,同时,这个i值也是最后一次被循环体赋值的值,就是i=2。所以,你所有生成的函数,其实都一样,i永远等于2.建议看我的教程,熟悉javascript的闭包。
    http://iamduyu.cn/?tag=javascript
      

  6.   

    造成这个结果确实不是因为闭包,是因为当前版本的JavaScript版本中不存在块作用域。修正这个问题用到的是闭包,如#2 sundotLei所示。另外也可以使用with进行修正:
    var a=[1,2,3];
    for(i in a){
      with({i:i}){
          a[i] = function (){
            return i*i;
          };
      }
    }
    alert(a[0]());
    alert(a[1]());
    alert(a[2]());参见:with与闭包的等同性
      

  7.   

    用闭包解决这个问题:
    var a=[1,2,3];
    for(i in a) {
        // use closure to keep current value in each loop
        (function() {
        
        var idx = i;
        a[idx] = function() {
            return idx*idx;
        };    })();
    }
    alert(a[0]());
    alert(a[1]());
    alert(a[2]());