AS3引用当前功能

时间:2011-07-28 01:27:45

标签: actionscript-3 actionscript methods scope

我刚刚遇到一个奇怪的场景,我想在一个没有名字的函数中使用removeEventListener()。我的意思是,我在addEventListener()中创建了函数,而不是引用一个函数:

addEventListener(
    Event.ENTER_FRAME, 
    function(e:Event):void
    {
        if(getTimer() > 8000)
        {
            // removeEventListener(Event.ENTER_FRAME, <<this function>>);
            // Other stuff
        }
    }
);

是否可以引用当前函数(即我正在使用的函数)?或者我只需要以标准方式构建上述内容?

请注意,我完全清楚您可以使用许多可用的标准化方法来实现上述目标,它纯粹是一个示例代码段。

3 个答案:

答案 0 :(得分:15)

有两个选项,您可以为其命名(有三种方法可以执行此操作),也可以使用arguments.callee

对于前者,在AS3中命名函数的三种方法是:

class Foo
{
    // class (static or member) level
    public function bar():void
    {
       // use a variable (technically, this function is anonymous, but we can
       // still use the variable to reference the function itself.
       var inVariable:Function = function():void
       {
          // declare it in a local scope
          function local():void
          {

          }
       }
    }
}

使用命名函数:

function callback(e:Event):void {
    trace("tick");
    removeEventListener(Event.ENTER_FRAME, callback);
}
addEventListener(Event.ENTER_FRAME, callback);

使用arguments.callee:

addEventListener(
    Event.ENTER_FRAME, 
    function(e:Event):void
    {
        if(getTimer() > 8000)
        {
            // I get superstitious and I use a local variable.
            var callee:Function = arguments.callee
            removeEventListener(event.type, callee);
            // Other stuff
        }
    }
);

答案 1 :(得分:2)

你只需要给它一个名字,例如:

addEventListener(Event.ENTER_FRAME, function callback(e:Event):void {
    trace("tick");
    removeEventListener(Event.ENTER_FRAME, callback);
});

在这个例子中,“tick”只会被追踪一次。

答案 2 :(得分:2)

在actionscript中使用匿名函数是一个糟糕的选择,因为它非常慢。他们几乎不能被垃圾收集。还可以提一下,这只有在调用监听器时才会起作用(是的,如果是enter_frame的话),所以在匿名函数之外其他函数无法删除监听器。除此之外,is还是一个使用单独函数的actionscript约定,这使得您的代码更具可读性,并且只需要几个额外的字符(仅为其命名)。

addEventListener(Event.ENTER_FRAME, onEnterFrame);

function onEnterFrame(e:Event):void
{
    if(getTimer() > 8000)
    {
         removeEventListener(Event.ENTER_FRAME, onEnterFrame);
    }
}

如果您想要一种更简单的方法来删除事件监听器;您可以从目标对象中检测侦听器的类型和函数被调用者。但是我认为这也会使代码的可读性降低。

e.target.removeEventListener(e.type, arguments.callee);

<强>来源
http://jacksondunstan.com/articles/413
http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html