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,我把自己的理解写在代码后面了。还请大神帮忙解释下这个代码块的执行情况
第一步
关于fnlist的值是这个应该是没有异议的吧。如果你认为是
function(){alert(item0/1/2+" "+list[0/1/2])}
那就要搞清楚函数未执行的时候只是初始的函数体,内部变量和参数是不会有具体值的,只是个变量。
第二步
就是要搞清楚
item
和i
这两个变量是什么值了。1.注意fnlist[i]()调用的时候你并没有向函数传入参数。
2.而函数内部
function(){alert(item+" "+list[i])}
有没有对这两个变量赋值。3.所以要去外部作用域找
item
和i
的值。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])}
中的item
和i
都是同一个值。相关知识点有'
上下文环境
'、'作用域链
',然后可以再看一下闭包
和es6 let