2009-07-14 5 views
0

У меня есть массив функции обратного вызова, как это:Как я могу использовать указатель на метод экземпляра объекта?

class Blah { 
    private var callbacks : Array; 

    private var local : Number; 

    public function Blah() { 
     local = 42; 

     callbacks = [f1, f2, f3]; 
    } 

    public function doIt() : Void { 
     callbacks[0](); 
    } 

    private function f1() : Void { 
     trace("local=" + local); 
    } 

    private function f2() : Void {} 
    private function f3() : Void {} 

} 

Если я запускаю этот код, я получаю «локальный = не определено» вместо «местного = 42»:

blah = new Blah(); 
blah.doIt(); 

Итак, Указатели функций Flash не имеют контекста. Каков наилучший способ решить эту проблему?

ответ

1

Try:

callbacks[0].apply(this, arguments array)

или

callbacks[0].call(this, comma-separated arguments)

Если вы хотите, чтобы "нести контекст" попробовать:

public function doIt() : Void { 
    var f1() : function(): Void { 
     trace("local=" + local); 
    } 

    f1(); 
} 

Это создает замыкание на this.local в expecte d

1

Самый простой способ - использовать класс Delegate ... он работает с использованием техники, описанной в Vlagged ... хотя я должен изменить, что я вообще не понимаю код (это также синтаксически неверно). ..

иначе, попробуйте это:

class AutoBind { 
    /** 
    * shortcut for multiple bindings 
    * @param theClass 
    * @param methods 
    * @return 
    */ 
    public static function methods(theClass:Function, methods:Array):Boolean { 
     var ret:Boolean = true; 
     for (var i:Number = 0; i < methods.length; i++) { 
      ret = ret && AutoBind.method(theClass, methods[i]); 
     } 
     return ret; 
    } 
    /** 
    * will cause that the method of name methodName is automatically bound to the owning instances of type theClass. returns success of the operation 
    * @param theClass 
    * @param methodName 
    * @return 
    */ 
    public static function method(theClass:Function, methodName:String):Boolean { 
     var old:Function = theClass.prototype[methodName]; 
     if (old == undefined) return false; 
     theClass.prototype.addProperty(methodName, function():Function { 
      var self:Object = this; 
      var f:Function = function() { 
       old.apply(self, arguments); 
      } 
      this[methodName] = f; 
      return f; 
     }, null); 
     return true; 
    } 
} 

и добавить его в качестве последнего заявления в скучное:

private static var __init = AutoBind.methods(Blah, "f1,f2,f3".split(",")); 

, что будет делать трюк. .. обратите внимание, что вызовы f1, f2 и f3 будет медленнее, хотя, потому что они нуждаются в один дополнительный вызов функции ...

Greetz

back2dos

+0

спасибо, но это, кажется, немного излишним – andrewrk

Смежные вопросы