actionscript-3 - Flash AS3函数跟踪相同的值

标签 actionscript-3 flash

有人可以解释为什么下面的跟踪返回数组的长度而不是数组项中“i”的值吗?

非常感谢,尼克

AS3

function createMarkers(mapLocations){
    var markerArray:Array = new Array();
    for(i=0; i<mapLocations.length; i++){
        markerArray.push(new marker());
        markerArray[i].x=mapLocations[i][1];
        markerArray[i].y=mapLocations[i][2];

        markerArray[i].markerText.text = mapLocations[i][0].toString();
        markerArray[i].addEventListener(MouseEvent.CLICK, function(e:MouseEvent){clickTarget(e,i);});
        bgImage.addChild(markerArray[i]);
    }
}

function clickTarget(e:MouseEvent,a){
    trace(a);
}

最佳答案

这是处理 JavaScript/ActionScript 函数时的常见错误。您之所以遇到问题,是因为函数是闭包,这意味着它们在定义函数时保存对作用域中定义的变量的引用。

这意味着您的匿名处理函数关闭围绕i变量,但它存储对其的引用,而不是其值。由于 i 发生变化,每个函数都保存对同一变量的引用,该变量仅保存分配给它的最后一个值。

基本上,如果您想要关闭变量的特定值,则必须在函数作用域内声明该变量(使用var 语句)。因此,这看起来应该可行:

for (var i:int = 0; i < 10; i++) {
    var scopedI:int = i;
    mc[i].addEventListener(MouseEvent.CLICK, function (e:MouseEvent) { trace(scopedI); });
}

我们在循环范围内声明一个新变量 scopedI 来专门关闭该值,因为该变量将在循环的每次迭代中使用唯一值重新声明。不幸的是,ActionScript 和 JavaScript 一样,没有 block 级作用域,只有函数级作用域,因此所有变量声明都“提升”到函数的顶部。

这几乎意味着您的 scopedI 类型与 i 以及该函数内声明的任何其他变量具有相同的作用域。那么,我们如何创建一个新的范围呢?具有更多功能。请记住,在 ActionScript 中,函数是对象,因此我们可以做如下疯狂的事情:

(function (id) {
    return function () { trace(id); };
})(7);

这段代码创建了一个函数,然后立即使用 id 参数的值 7 执行该函数。这很有用,因为现在 id 的作用域是我们返回的内部函数,因此无论外部发生什么,该函数都将始终打印“7”。

同样,我们可以使用它来确定循环中的 i 变量的范围。您的代码可以更新为如下所示:

function createMarkers(mapLocations){
    var markerArray:Array = new Array();
    for(var i = 0; i < mapLocations.length; i++){
        markerArray.push(new marker());
        markerArray[i].x = mapLocations[i][1];
        markerArray[i].y = mapLocations[i][2];

        markerArray[i].markerText.text = mapLocations[i][0].toString();
        markerArray[i].addEventListener(MouseEvent.CLICK, (function (scopedI) {
                return function (e:MouseEvent) { clickTarget(e, scopedI); };
            })(i));
        bgImage.addChild(markerArray[i]);
    }
}

function clickTarget(e:MouseEvent, a){
    trace(a);
}

现在,scopedI 对于每次迭代都是唯一的。是的,语法有点困惑,但这最终成为该语言的一个极其强大和富有表现力的功能。如果你能理解它,它会非常有用。

关于actionscript-3 - Flash AS3函数跟踪相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14025783/

相关文章:

actionscript-3 - AS3 中的 PBKDF2WithHmacSHA1

actionscript-3 - 即使我已经导入了 Stage 类,为什么我的 Actionscript 3 类中的 stage 仍未定义?

Flash 预加载器仅从 90% 开始

flash - 谷歌是反Flash的吗?

apache-flex - 如何防止 Flash 的 URLRequest 转义 url?

flash - 在 ActionScript 中剪切声音

flash - 在要进行 GC 的对象中将引用设置为 null?

apache-flex - 从 itemRenderer 调用父函数

macos - Mac 上的 flash cookie 存储在哪里?

flash - Flash 是否支持泛型(强类型集合或数组)?