我试图找出为什么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有很好的经验并帮助我?
非常感谢!
答案 0 :(得分: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();
}
}