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,达到我们想要的结果
时间: 2024-10-20 19:22:07