首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为事件处理程序使用闭包的ActionScript 3.0

为事件处理程序使用闭包的ActionScript 3.0
EN

Stack Overflow用户
提问于 2008-10-07 18:06:10
回答 7查看 9.9K关注 0票数 15

我试过这样做:

代码语言:javascript
复制
root.addEventListener("click", 
   function () 
   { 
      navigateToURL(ClickURLRequest,"_self"); 
   });

并且它确实添加了事件侦听器。我喜欢使用闭包,因为它们在这种情况下工作得很好。

但是,删除事件侦听器需要引用原始函数,因为我使用了匿名闭包,所以它不起作用,我尝试了:

代码语言:javascript
复制
   root.removeEventListener("click", 
       function () 
       { 
          navigateToURL(ClickURLRequest,"_self"); 
       });

以及:

代码语言:javascript
复制
   root.removeEventListener("click", function () {} );

我发现它唯一有效的方法是抛弃匿名闭包,将事件侦听器指向一个预先存在的函数:

代码语言:javascript
复制
 function OnClick (e:Event)
 {
     navigateToURL(ClickURLRequest,"_self");
 }

 root.addEventListener("click", OnClick);
 root.removeEventListener("click", OnClick);

有没有人知道如何对事件处理程序使用匿名闭包,同时保留删除它们的能力?

EN

回答 7

Stack Overflow用户

发布于 2008-10-07 19:11:53

下面是删除我在生产项目中使用过的事件侦听器的一般方法

代码语言:javascript
复制
addEventListener
(
    Event.ACTIVATE, 
    function(event:Event):void
    {
        (event.target as EventDispatcher).removeEventListener(event.type, arguments.callee)             
    }
)
票数 36
EN

Stack Overflow用户

发布于 2010-10-09 06:17:20

如前所述,您可以从闭包本身的侦听器链中删除闭包。这是通过使用arguments.callee完成的:

代码语言:javascript
复制
myDispatcher.addEventListener("click", function(event:Event):void
{
    IEventDispatcher(event.target).removeEventListener(event.type, arguments.callee);

    // Whatever else needs doing goes here
});

这将有效地将闭包转换为事件的一次性侦听器,只需在事件触发后将其自身分离。虽然在语法上冗长,但对于那些真正只触发一次(或者你只关心一次)的事件来说,它是一种令人难以置信的有用技术,例如,在Flex中使用"creationComplete“。在下载数据时,我一直在使用它,因为我认为内联回调代码会更容易理解。这就像隐藏了异步性:

代码语言:javascript
复制
myLoader.addEventListener("complete", function(event:Event):void
{
    /* Even though the load is asynchronous, having the callback code inline
     * like this instead of scattered around makes it easier to understand,
     * in my opinion. */
});

但是,如果您想要多次监听事件,由于显而易见的原因,这将不会非常有效。在这种情况下,您需要在某个地方存储对闭包的引用。方法与ActionScript中的任何其他对象一样,都是可以传递的对象。因此,我们可以将代码修改为如下所示:

代码语言:javascript
复制
var closure:Function;

myDispatcher.addEventListener("click", function(event:Event):void
{
    closure = arguments.callee;

    // Whatever else needs doing goes here
});

当您需要删除事件侦听器时,使用'closure‘引用,如下所示:

代码语言:javascript
复制
myDispatcher.removeEventListener("click", closure);

显然,这是一个抽象的例子,但是使用像这样的闭包是非常有用的。但是,它们也有缺点,比如效率低于命名方法。另一个缺点是,如果需要的话,您实际上必须存储对闭包的引用。然后,必须注意保持该引用的完整性,就像任何其他变量一样。

因此,虽然不同的语法可能有其用途,但它并不总是最好的解决方案。这是一种苹果和橙子之类的东西。

票数 7
EN

Stack Overflow用户

发布于 2008-10-07 18:30:31

您可以将function()关键字看作一个构造函数,每次创建一个新对象(闭包)。因此,如果您只将闭包创建为一个参数,而没有在任何地方保留引用,那么就没有办法在其他地方获得“相同”的闭包。

最明显的解决方案是你不喜欢的,在使用函数之前定义它。当然,它仍然可以是一个完整的闭包,而不仅仅是一个“静态的”函数。只需在您想要的上下文中定义它,并将其分配给一个局部变量。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/179668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档