Mozilla Rhino Function内部函数提取

问题描述 投票:2回答:1

我试图弄清楚为什么Rhino无法在函数内部获取函数对象。

根据Rhino文档,这是从Java端在javascript中提取函数的方法。

Object fObj = scope.get("f", scope);
if (!(fObj instanceof Function)) {
    System.out.println("f is undefined or not a function.");
} else {
    Object functionArgs[] = { "my arg" };
    Function f = (Function)fObj;
    Object result = f.call(cx, scope, scope, functionArgs);
    String report = "f('my args') = " + Context.toString(result);
    System.out.println(report);
}

如果我有这个javascript,它将可以正常使用:

function f(){
    //some lines
}

但是,问题是这样的:

假设我有一个像这样的java函数:

class RemoteJavaClass{
public void extractJavaScript(String targetFunctionName){
    Object fObj = scope.get(targetFunctionName, scope);
    if (!(fObj instanceof Function)) {
        System.out.println(targetFunctionName + " is undefined or not a function.");
    }
}
} 

以及abc.js文件中的此类javascript:

function foo(){
    function inner(){
        //something
    }

    remrem.extractJavaScript("inner");
}
foo()

在从Java执行abc.js之前,我将必须按照以下步骤“注入”变量remrem(以使javascript能够调用Java函数:]

public void main (String args[]){
     scope = cx.initStandardObjects(new ImporterTopLevel(cx));
     RemoteJavaClass inst = new RemoteJavaClass();

     //inject the inst to javascript with variable "remrem"
     ScriptableObject.putProperty(scope, "remrem", Context.javaToJS(inst, scope));

    //finally we execute the script
    String scriptString = (read the javascript text from abc.js)
    Object result = cx.evaluateString(scope, scriptString, "Title", 1, null);
}

输出将是:

 "inner is undefined or not a function."

但是,如果脚本看起来像这样,那么Rhino将能够提取inner。如果整个事情不在函数内部,那么Rhino提取内部函数将没有任何问题。

function inner(){
    //something
}
remrem.extractJavaScript("inner");

我已经在示波器上玩了很多,尝试了一下,但是没有用。假设是Rhino在全局范围内寻找内部,因此我继续尝试在函数范围内进行查找,但无济于事,它没有用。

Object fObj = scope.get("f", scope);
if (!(fObj instanceof Function)) {
    System.out.println("f is undefined or not a function.");
} else {
    Object functionArgs[] = { "my arg" };
    Function f = (Function)fObj;
    Object result = f.call(cx, **fObj**, **fObj**, functionArgs);
    String report = "f('my args') = " + Context.toString(result);
    System.out.println(report);
}

仍然还是我出现了错误:

org.mozilla.javascript.UniqueTag@11769f4c: NOT_FOUND

有人在Rhino上有很好的经验,可以帮助我吗?

非常感谢!

javascript java mozilla rhino
1个回答
0
投票

我知道这个问题确实很老,但是由于我上周一直在努力解决类似的问题,因此希望我的回答对其他具有相同主题的人有所帮助。您以为Rhino在全局范围内查找是正确的,因此您需要首先访问foo函数的范围。但是,您不能像这样访问JavaScript中的内部函数。一种方法是遵循显示模块模式。您可以通过以下链接查看有关此模式的更多信息:JavaScript Module Pattern Basics

所以,一种方法是像下面这样编写脚本:

// Define the Foo module
var Foo = (function() {
    // Variables and other module functions
    // ...

    function inner() {
    }

    // Export public functions of the module
    return {
        inner: inner
    };
})();

然后,使用Rhino,您可以像下面那样访问内部函数:

Context context = Context.enter();

// Assume that the script is stored in a String variable called "s"

try {
    ScriptableObject globalScope = context.initStandardObjects();
    context.evaluateString(globalScope, s, "script", 1, null);

    // We now have access to the scope of the Foo module
    ScriptableObject fooScope = (ScriptableObject) globalScope.get("Foo", globalScope);
    final Function function = (Function) fooScope.get("inner", fooScope);
    final Object result = function.call(context, fooScope, fooScope, new Object[] {});

    // ...          
    } finally {
        Context.exit();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.