javascript中,for循环里匿名函数中的变量的取值是怎样的?

function buildList(list){
       var result=[];
       for(var i=0;i<list.length;i++){
           var item="item"+i;
           result.push(function(){
               alert(item+" "+list[i])
           });
       }
       return result;  //返回一个匿名函数数组
   }
   

function testList(){
       var fnlist=buildList([0,1,2]); //返回一个有三个匿名函数元素的数组
       for(var i=0; i<fnlist.length;i++){  //fnlist数组的长度为3,
           fnlist[i]();              //我觉得此处应该是fnlist[0]():“item0 0”; fnlist[1]():“item1 1”; fnlist[2]():“item2 2”;
       }
   }

   testList();                              //实际结果是"item2 undefined" 3 times

不理解为什么最后弹出的结果是"item2 undefined" 3 times,我把自己的理解写在代码后面了。还请大神帮忙解释下这个代码块的执行情况

阅读 3.9k
3 个回答

第一步

fnlist = [
function(){alert(item+" "+list[i])},
function(){alert(item+" "+list[i])},
function(){alert(item+" "+list[i])}
]

关于fnlist的值是这个应该是没有异议的吧。如果你认为是
function(){alert(item0/1/2+" "+list[0/1/2])}
那就要搞清楚函数未执行的时候只是初始的函数体,内部变量和参数是不会有具体值的,只是个变量。

第二步

就是要搞清楚itemi这两个变量是什么值了。
1.注意fnlist[i]()调用的时候你并没有向函数传入参数。
2.而函数内部function(){alert(item+" "+list[i])}有没有对这两个变量赋值。
3.所以要去外部作用域找itemi的值。
4.var item="item"+i;这个语句最后一次执行是i=2的时候,所以item='item2'
5.i的值是在i=2执行完循环体,后又执行了i++,发现不满足i<list.length,所以此时i=3,所以list[i]=undefined
6.我并没有区分fnlist[0]()、fnlist[1]()、fnlist[2](),是因为他们执行的时候查找的function(){alert(item+" "+list[i])}中的itemi都是同一个值。


相关知识点有'上下文环境'、'作用域链',然后可以再看一下闭包es6 let

执行buldList函数中只是把匿名函数push到了数组中,但是没有执行匿名函数,buldList执行完毕后里面的 “i” 已经变成 3 了;
所以执行testList时的 才是执行匿名函数(function(){alert(item +" "+list[i])}()),因此结果都是item2!

undefined原因:list[3]不存在,所以为undefined

道理楼上的都说了,在你代码上改一下就可以实现你的想法,加深理解

function buildList(list){
   var result=[];
   for(var i=0;i<list.length;i++){
       var item="item";
       result.push(function(i){//这里
           console.log(item+i+" "+list[i])//这里
       });
   }
   return result;  
}

function testList(){
   var fnlist=buildList([0,1,2]);
   console.log(fnlist)
   for(var i=0; i<fnlist.length;i++){  
       fnlist[i](i);//这里
   }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题