在运行时重新定义命名函数

时间:2011-03-26 02:53:00

标签: actionscript-3

我想做的事情有点奇怪,但我想知道是否有人能想出一个聪明的方法去做我想做的事情。基本上,我想在运行时重新定义一个命名函数。我可以使用匿名函数执行此操作,但我无法找到为命名函数执行此操作的方法。我想这样做,以便我可以在一个对象上实现一个“间谍”功能,用于测试框架(Jasmine到Flex的端口)。

举例来说,这个课程:

public class TestClass
{
    public var anonymous:Function = function():void { 
        trace("original anonymous"); 
    };

    public function named():void {
        trace("original named");
    }
}

我可以轻松地重新定义匿名函数,因为它只是一个变量。 Javascript使用这个习惯用法很多。

var testClass:TestClass = new TestClass();
testClass.anonymous = function():void { trace("overridden anonymous"); }

但是,当我对命名函数执行相同的操作时,会出现编译时错误:

// Does not compile
testClass.named = function():void { trace("overridden named"); }

我试图让它更加“软弱”,但这会导致运行时失败“无法分配给在TestClass上命名的方法”。

// Compiles with runtime failure
testClass["named"] = function():void { trace("overridden named"); }

任何人都可以比我想出的方法更聪明吗?字节码可以被劫持吗?什么?

3 个答案:

答案 0 :(得分:1)

  

我想修改一个对象,而不是一个   类

但是对象不包含函数,只包含非静态变量。我尝试使用prototype属性并在那里替换方法,但原始方法仍然被调用而不是注入一个。

关于“hack”字节码,你的意思是“hack”已经在运行时加载了SWF吗?我认为这是不可能的。不过,我确定你可以用as3swf解析SWF,在字节码中查找方法,替换它并将结果保存在新的SWF中。

答案 1 :(得分:0)

我有一个关于制作“缓存”功能的想法。这可能适合您的需要。

假设你有一个“Car”类,你需要在运行时重新定义一个方法:

public class Car extends Sprite
{
    private var functionCache:Function;

    public function Car()
    {
        super();
    }

    public function flexibleFunction(functionBody:*=null):void{
        if(functionBody is Function){
            functionBody.call();
            functionCache=functionBody;
        } else {
            functionCache(functionBody);
        }
    }
}

用法:

public class Main extends Sprite
{
    private var car:Car;

    public function Main()
    {
        car = new Car();

        car.flexibleFunction(function(){trace("redefine test #1")});

        car.flexibleFunction();

        car.flexibleFunction(function(doParametersWork:String="let's see"){trace("redefine test #2: " + doParametersWork);});

        car.flexibleFunction("yes they do");

        car.flexibleFunction();

    }
}

答案 2 :(得分:0)

实现目标的简单方法是简单地将新函数传递给原始函数并从那里执行:

package
{
//Imports
import flash.display.Sprite;

//Class
public class RedefineFunction extends Sprite
    {
    //Constructor
    public function RedefineFunction()
        {
        originalFunction();

        originalFunction(redefinedFunction);
        }

    //Original Function
    public function originalFunction(redefinition:Function = null):void
        {
        if  (redefinition != null)
            redefinition();
            else
            trace("Original Function Definition");
        }

    //Redefined Function
    private function redefinedFunction():void
        {
        trace("Redefined Function Definition")
        }
    }
}

迹线:

Original Function Definition
Redefined Function Definition