有人可以解释为什么以下代码的跟踪结果是“5,5,5,5,5”而不是“1,2,3,4,5”,你如何使匿名函数引用收集数组中的元素?(在本例中,“var item”应该是引用列表[0],[1],[2],[3],[4])。
var list:Array=[1,2,3,4,5];
var funcs:Array=[];
for each(var item:int in list){
funcs.push( function(){
trace(item);
});
}
for each(var func:Function in funcs){
func();
}
trace result: 5,5,5,5,5
答案 0 :(得分:3)
您的代码存在的问题是您创建了一个稍后可以访问的闭包。 对于您想要做的事情,您需要创建多个可以在以后访问的闭包。
var list:Array=[1,2,3,4,5];
var funcs:Array=[];
var closure_factory = function(index) {
return function() { trace(index); };
};
for each(var item:int in list){
funcs.push(closure_factory(item));
}
for each(var func:Function in funcs){
func();
}
答案 1 :(得分:2)
这是两件事的结果:
AS3中的函数级范围:for each(var item:int in list)
中的变量声明等同于在函数开头声明var item:int
(在您的示例中,在代码的开头)
匿名函数是闭包,它不仅包含您指定的代码trace(item)
,还包含运行该代码的环境。具体来说,您的代码创建的每个匿名函数都知道它应该使用item
变量(在函数范围内声明)进行打印(通过trace()
)。
所以,会发生的事情是item
被赋予list
的所有元素,然后保留最后一个值(即5)。它存在(不会超出范围),当这些匿名函数触发时,每个函数都会查看相同的item
并打印相同的值。