在回调函数中调用类的方法时,不能使用this
对象
要在javascript中调用该方法,我声明that
变量,将this
分配给that
,并在回调中使用that
来调用this
的方法。
在动作脚本中,我是否必须像在javascript中那样做?
以下代码是使用that
在回调内调用方法的示例
动作中有更简单的方法吗?
class C {
private var that:C;
function C() {
that = this
}
public function f1():void {
var sp:Sprite = new Sprite;
sp.addEventListener(MouseEvent.CLICK, function():void {
this.f2(); // this doesn't work
that.f2(); // that works
});
}
public function f2():void {
trace('hello');
}
}
答案 0 :(得分:6)
如果您将回调函数设为C类的方法,则可以访问this
。
public class C
{
private function f1():void
{
var sp:Sprite = new Sprite();
sp.addEventListener(MouseEvent.CLICK, callback);
}
private function callback(event:MouseEvent):void
{
this.f2();
}
private function f2():void
{
trace("Hello World");
}
}
现在this
引用了类C的实例,其范围是整个类。
答案 1 :(得分:5)
这是另一种方法:
package some.package {
class SomeSprite extends Sprite {
public function f1():void
{
var sprite1:Sprite = new Sprite;
sprite1.addEventListener(MouseEvent.CLICK,
(new Closure(f2, this, ["Hello"], sprite1).handler));
var sprite2:Sprite = new Sprite;
sprite2.addEventListener(MouseEvent.CLICK,
(new Closure(f2, this, ["Bye Bye"], sprite2).handler));
}
private function f2(message:String):void
{
trace(message);
}
}
}
class Closure {
public var callback:Function;
public var thisObj:Object;
public var params:Array;
public var dispatcher:IEventDispatcher;
public var cleanAfterCallback:Boolean = true;
function Closure(callback:Function, thisObj:Object,
params:Array, dispatcher:IEventDispatcher)
{
this.callback = callback;
this.thisObj = thisObj;
this.params = params;
this.dispatcher = dispatcher;
}
public function handler(e:Event):void
{
callback.apply(thisObj, params);
if (cleanAfterCallback)
dispatcher.removeEventListener(e.type, eventHandler)
}
}
答案 2 :(得分:2)
请参阅Adobe网站上的Function Documentation。使用apply“thisArg”等于你想要调用成员函数的对象,“this”将是正确的。
答案 3 :(得分:2)
这不是一个答案,但更多的是解释为什么内联闭包是一个内存泄漏,来自@js _的评论请求。
Flash中的内存管理有两种方式;引用计数和标记和扫描(查看http://divillysausages.com/blog/tracking_memory_leaks_in_as3以获得更深入的内容)。
内存泄漏来自addEventListener()
电话。默认情况下,addEventListener
将创建对其正在侦听的对象的引用 - 例如,您的匿名函数将保存对对象的引用。
你可以把它变成一个弱的监听器,但因为你的函数是匿名的,所以它没有其他的引用,这意味着如果你的事件监听器很弱,它会在函数结束时被收集(如果你使用的话,也是如此)一个局部变量)。
因此,要使匿名函数起作用,您需要使事件侦听器变得强大。但是当你来删除监听器时,你无法访问匿名函数,所以你无法删除它。最好的情况是,您丢失了为回调分配的内存。最糟糕的情况是,匿名函数对您的对象的引用意味着当Flash认为它仍然在使用时,对象本身永远不会被收集(可以链接)。
如果对象本身最终没有其他引用,除了事件侦听器之外,那么两者都应该在标记和扫描阶段收集(因为这是设计时考虑到这样的循环引用)。也就是说,你从来没有真正想要标记和扫描 - 它很慢(你可能会注意到你的程序中经常出现暂停)并且只有在内存使用开始失控时才开始。你想自己控制引用计数
答案 4 :(得分:1)
您正在使用内联函数闭包,因此您要查找的this
将不在该范围内。在javascript中函数闭包非常相似(如果不相同)。上面的方法很好。还有其他方法可以做到这一点,但不一定更简单,这取决于您的实现。
function():void {
this.f2(); // this is scoped only to within this function
that.f2(); // that has reference to the global object this
}
请阅读ActionScript文档中的以下内容
Function Closures
Event listeners
答案 5 :(得分:0)
如果你做了一个跟踪(这个),它会说[function Global]。这就是为什么它不起作用。