首页 > 代码库 > js中闭包for循环

js中闭包for循环

var a=[];
for(var i=0;i<10;i++){
    a[i]=function(){
        alert(i);
    }
}
alert(i);    //10
a[0]();        //10
a[9]();        //10

  为什么a[0]到a[9]都是10,而不是我们想像中的0到9呢?

  我的理解是js的作用域导致的.

  首先来看参数的传递.js是按值传递的,源代码中的a[i]=function(){alert(i)},a[i]保存的是一个指向堆内存的地址(对象和方法在js中保存在堆内存中).当每一次for循环时:a[0]=function(){...},a[1]=function(){...},一直到a[9]=function(){...},循环改变的是a[0]到a[9],a[i]里的function(){...}毫无变化,仍然是一个指向堆内存的字符串.那么又引出一个新问题,为什么不增加function(){...}里面的i,因为匿名函数不能自我执行.当最后调用a[0]到a[9]时,保存着匿名函数地址的字符串才真正去在堆内存中找方法执行,这时for循环早已结束,结果都是10.

  将代码改成a[i]=i;a[i]保存的是一个基本类型值,可以得到a[0]=0 ...... a[9]=9.因为没有作用域链的限制.

var b=[];
for(var j=0;j<10;j++){
    b[j]=function(){
        return j;
    }()
}

alert(j);           //10
alert(b[0]);        //0
alert(b[9]);        //9

  将匿名函数自动执行,并且赋值给b,达到我们想要的结果

 

js中闭包for循环