匿名函数中变量的奇怪行为?

时间:2013-04-05 08:14:10

标签: actionscript-3 flash function variables anonymous-function

有人可以解释为什么以下代码的跟踪结果是“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

2 个答案:

答案 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)

这是两件事的结果:

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

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

  3. 所以,会发生的事情是item被赋予list的所有元素,然后保留最后一个值(即5)。它存在(不会超出范围),当这些匿名函数触发时,每个函数都会查看相同的item并打印相同的值。