闪存AS3函数轨迹相同的值闪存、函数、轨迹

2023-09-08 14:16:45 作者:〝轉身流淚 っ

可能有人可能解释为什么跟踪之下返回数组的长度,而不是价值的i的数组项?

非常感谢,尼克

AS3

 函数createMarkers(mapLocations){
    VAR markerArray:阵列=新的Array();
    对于(i = 0; I< mapLocations.length;我++){
        markerArray.push(新的标记());
        markerArray [I] .X = mapLocations [Ⅰ] [1];
        markerArray [I] .Y = mapLocations [I] [2];

        markerArray [I] .markerText.text = mapLocations [I] [0]的ToString();
        markerArray [I] .addEventListener(MouseEvent.CLICK,功能(E:的MouseEvent){clickTarget(E,I);});
        bgImage.addChild(markerArray [I]);
    }
}

功能clickTarget(E:的MouseEvent,A){
    微量(一);
}
 

解决方案

这是一个常见的​​错误时,使用JavaScript / ActionScript函数处理。您遇到的问题,因为功能的关闭的,这意味着它们持有的引用的范围定义的变量的函数定义的时候。

Excel中如何利用函数实现数据重复的检查

这意味着匿名处理函数的关闭的周围的变量,但它存储对它的引用,而不是它的价值。由于的变化,每个函数持有引用相同的变量,这将只是抱着分配给它的最后一个值。

基本上,如果你要紧密围绕一个变量的特定值,你要的声明的变量(使用 VAR 语句)内函数的范围。正因为如此,这可能看起来像它应该工作:

 的(VAR我:= 0;我小于10;我++){
    VAR scopedI:INT =我;
    MC [I] .addEventListener(MouseEvent.CLICK,功能(E:的MouseEvent){跟踪(scopedI);});
}
 

我们声明一个新的变量, scopedI ,环路范围内紧密围绕该值具体而言,由于该变量将被重新声明循环每次迭代具有独特价值。不幸的是,动作脚本,如JavaScript,做的没有的有块级范围,唯一的功能水平范围,因此所有的变量声明红旗的函数的顶部。

这pretty的多只是意味着你 scopedI 类型具有相同的范围为,以及作为函数内声明的任何其他变量。那么,我们怎样才能创建一个新的范围有多大?随着越来越多的功能。请记住,在ActionScript中,函数是对象,所以我们可以做疯狂的事情是这样的:

 (功能(ID){
    复位功能(){跟踪(ID); };
})(7);
 

的code这一点创建了一个函数,然后立即用 7 ID 参数。这是有用的,因为现在 ID 的作用范围,这是我们返回内部功能,该功能将始终打印7,无论发生什么事外。

同样,我们可以在循环使用这个范围我们的变量。您的code可以进行更新,以这样的:

 函数createMarkers(mapLocations){
    VAR markerArray:阵列=新的Array();
    对于(VAR I = 0; I< mapLocations.length;我++){
        markerArray.push(新的标记());
        markerArray [I] .X = mapLocations [Ⅰ] [1];
        markerArray [I] .Y = mapLocations [I] [2];

        markerArray [I] .markerText.text = mapLocations [I] [0]的ToString();
        markerArray [I] .addEventListener(MouseEvent.CLICK,(函数(scopedI){
                返回功能(E:的MouseEvent){clickTarget(即scopedI); };
            })(一世));
        bgImage.addChild(markerArray [I]);
    }
}

功能clickTarget(E:的MouseEvent,A){
    微量(一);
}
 

现在, scopedI 将是唯一的每个迭代。是的,语法是有点乱,但这最终被语言的一个非常强大和前pressive功能。如果你能理解它,它是非常有用。

Could somebody possibly explain why the trace below returns the length of the array rather than the value of the "i" in the array item?

Many thanks, Nick

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);
}

解决方案

This is a common mistake when dealing with JavaScript/ActionScript functions. You're having the problem because functions are closures, which means they hold references to the variables defined in scope when the functions are defined.

This means that your anonymous handler function closes around the i variable, but it stores a reference to it, not its value. Since i changes, every function holds a reference to the same variable, which will just hold the last value assigned to it.

Basically, if you want to close around a variable's specific value, you have to declare the variable (using the var statement) within the function's scope. Because of that, this might look like it should work:

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

We declare a new variable, scopedI, within the loop's scope to close around that value specifically, since that variable will be redeclared every iteration of the loop with a unique value. Unfortunately, ActionScript, like JavaScript, does not have block-level scope, only function level scope, so all variable declarations are "hoisted" to the top of the function.

This pretty much just means that your scopedI type has the same scope as i, as well as any other variable declared inside that function. So, how can we create a new scope? With more functions. Keep in mind that in ActionScript, functions are objects, so we can do crazy things like this:

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

That bit of code creates a function, then immediately executes it with a value of 7 for the id parameter. This is useful, because now id is scoped to the inner function which we return, so that function will always print "7", no matter what happens externally.

Likewise, we can use this to scope our i variable in the loop. Your code could be updated to look like this:

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);
}

Now, scopedI will be unique for each iteration. Yes, the syntax is a little bit messy, but this ends up being an extremely powerful and expressive feature of the language. If you can understand it, it's immensely useful.