【问题标题】:Mozilla Rhino Function inside function extractionMozilla Rhino Function inside 函数提取
【发布时间】:2016-07-26 21:02:15
【问题描述】:

我试图弄清楚为什么 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 将能够提取内部。如果整个事情不在函数内部,那么 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】:

    我知道这个问题真的很老了,但是由于我上周遇到了类似的问题,我希望我的回答能帮助其他有相同主题的人。假设 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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-02
      • 2016-08-04
      • 1970-01-01
      • 2010-12-01
      • 2016-05-25
      • 2017-05-06
      • 2011-06-06
      • 2010-11-11
      • 1970-01-01
      相关资源
      最近更新 更多