Как я могу использовать указатель на функцию экземпляра объекта? - PullRequest
0 голосов
/ 14 июля 2009

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

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 не имеют контекста. Как лучше всего решить эту проблему?

Ответы [ 2 ]

1 голос
/ 14 июля 2009

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

В противном случае попробуйте это:

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 станут медленнее, потому что им нужен один дополнительный вызов функции ...

Greetz

back2dos

1 голос
/ 14 июля 2009

Попробуйте:

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, как и ожидалось

...