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

У меня есть массив обратных вызовов функций, например:

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 {}

}

Если я запускаю этот код, я получаю «local=undefined» вместо «local=42»:

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

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


person andrewrk    schedule 14.07.2009    source источник


Ответы (2)


Пытаться:

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

or

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

Если вы хотите «нести контекст», попробуйте:

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

    f1();
}

Это создает закрытие this.local, как и ожидалось.

person Vlagged    schedule 14.07.2009

самый простой способ — использовать Delegate< /a> класс ... он работает с использованием методов, описанных 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;
    }
}

и добавьте это как самое последнее объявление в Blah:

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

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

приветствие

back2dos

person back2dos    schedule 14.07.2009