js中闭包for循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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循环的主要内容,如果未能解决你的问题,请参考以下文章

js闭包for循环总是只执行最后一个值得解决方法

JS中如何解决for循环中的延迟执行问题

js作用域for循环闭包问题

浅谈js for循环输出i为同一值的问题(闭包解决)

JS之经典for循环闭包问题解决方法

JS闭包导致循环给按钮添加事件时总是执行最后一个