3

谁能解释为什么下面代码的跟踪结果是“5,5,5,5,5”而不是“1,2,3,4,5”以及如何让匿名函数引用收集元素数组?(在这个例子中,“var item”应该是指 list[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
4

2 回答 2

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();
}
于 2013-04-05T10:45:55.170 回答
2

这是两件事的结果:

  1. AS3 中的函数级范围:内部变量声明for each(var item:int in list)相当于var item:int在函数开头声明 a (在您的示例中,在代码开头)。

  2. 匿名函数是闭包,它不仅包含您指定的代码,trace(item)还包含该代码运行的环境。具体而言,您的代码创建的每个匿名函数都知道它应该使用item变量(在函数范围内声明)用于打印(通过trace())。

因此,发生的情况是,它item被分配了 的所有元素list,然后保留最后一个值(即 5)。它存在(不会超出范围),并且当这些匿名函数触发时,它们中的每一个看起来都相同item并打印相同的值。

于 2013-04-05T09:17:37.993 回答