当前位置:  开发笔记 > 编程语言 > 正文

如何解决ActionScript 3(AS3)中的闭包问题

如何解决《如何解决ActionScript3(AS3)中的闭包问题》经验,为你挑选了1个好方法。

在下面的代码中,我试图加载一些图像,并在它们单独加载后立即将它们放入舞台.但它被窃听,因为只显示最后一张图像.我怀疑这是一个关闭问题.我该如何解决?AS3中的闭包行为与Java Script中的行为不一样吗?

var imageList:Array = new Array();
imageList.push({'src':'image1.jpg'});
imageList.push({'src':'image2.jpg'});
var imagePanel:MovieClip = new MovieClip();
this.addChildAt(imagePanel, 0);

for (var i in imageList) {
    var imageData = imageList[i];
    imageData.loader = new Loader();

    imageData.loader.contentLoaderInfo.addEventListener(
        Event.COMPLETE, 
        function() {
            imagePanel.addChild(imageData.loader.content as Bitmap);
            trace('Completed: ' + imageData.src);             
        });

    trace('Starting: ' + imageData.src);
    imageData.loader.load(new URLRequest(imageData.src));   
}

bobince.. 45

AS3中的闭包行为与Java Script中的行为不一样吗?

是的,JavaScript完全一样.和Python一样.和别的.

虽然在'for'中定义'var imageData',但for循环不会在这些语言中引入新的范围; 事实上,变量imageData绑定在包含范围内(外部函数,或者在这种情况下,它似乎是全局范围).您可以在循环完成执行后查看imageData并在其中查找imageList的最后一个元素来验证这一点.

因此,只有一个imageData变量,而不是循环的每次迭代都有一个变量.当COMPLETE触发时,它进入闭包并读取imageData 现在具有的任何值,而不是在定义函数时(*).通常,for循环将通过COMPLETE点完成,而imageData将保留最后一次迭代中的最后一个元素.

(* - 存在'早期绑定'语言,它将在您定义闭包评估变量的值.但ActionScript不是其中之一.)

可能的解决方案往往涉及使用外部函数来引入新范围.例如:

function makeCallback(imageData) { return function() {
    imagePanel.addChild(imageData.loader.content as Bitmap);
    trace('Completed: ' + imageData.src);                                                                                                     
} }
...
imageData.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, makeCallback(imageData));

你/可以/把这个内联,但双重嵌套的函数()开始变得难以阅读.

另请参见Function.bind()以获取可用于实现此功能的通用部分函数应用程序功能.它可能是未来JavaScript/ActionScript版本的一部分,并且可以在此期间通过原型设计添加到语言中.



1> bobince..:

AS3中的闭包行为与Java Script中的行为不一样吗?

是的,JavaScript完全一样.和Python一样.和别的.

虽然在'for'中定义'var imageData',但for循环不会在这些语言中引入新的范围; 事实上,变量imageData绑定在包含范围内(外部函数,或者在这种情况下,它似乎是全局范围).您可以在循环完成执行后查看imageData并在其中查找imageList的最后一个元素来验证这一点.

因此,只有一个imageData变量,而不是循环的每次迭代都有一个变量.当COMPLETE触发时,它进入闭包并读取imageData 现在具有的任何值,而不是在定义函数时(*).通常,for循环将通过COMPLETE点完成,而imageData将保留最后一次迭代中的最后一个元素.

(* - 存在'早期绑定'语言,它将在您定义闭包评估变量的值.但ActionScript不是其中之一.)

可能的解决方案往往涉及使用外部函数来引入新范围.例如:

function makeCallback(imageData) { return function() {
    imagePanel.addChild(imageData.loader.content as Bitmap);
    trace('Completed: ' + imageData.src);                                                                                                     
} }
...
imageData.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, makeCallback(imageData));

你/可以/把这个内联,但双重嵌套的函数()开始变得难以阅读.

另请参见Function.bind()以获取可用于实现此功能的通用部分函数应用程序功能.它可能是未来JavaScript/ActionScript版本的一部分,并且可以在此期间通过原型设计添加到语言中.


本质上不是,不是,但jQuery的sequence.Each()在每次迭代时调用一个函数,每次都重新绑定函数变量.因此,它避免了for/while循环可能遭受的问题.
推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有