首先让我承认我是JavaScript的菜鸟。因此,这个问题在基本情况下可能不是很合理,并且可能缺乏足够的信息来帮助我。
背景
我的组织内部有一个用于JavaScript的基于Eclipse的集成开发环境。我们所要做的就是用JavaScript编写脚本并直接执行它们。我的猜测是它使用Rhino,因为我在一些异常的堆栈跟踪中看到过它。
我的代码运行在3个".js“文件中。
脚本1:声明全局变量并将其实例化为Java对象
importClass(java.util.HashMap);
var hmTCResult = new HashMap();Script-2:使用Script-1中的全局变量执行一些操作
Script-2.prototype.run = function() {
hmTCResult.put("Result", "Fail");
};
changeStatus = function(strStatus){
hmTCResult.put("Result", strStatus);
};Script-3:调用Script-2中使用全局变量的函数
changeStatus("Pass") 问题定义
当我从Script-3调用Script-2中的函数时,似乎没有选择实例变量,我的函数失败了,即我得到了一个异常"hmTCResult not set to the instance of an object“。请注意,相同的变量hmTCResult在脚本1中运行良好。
我已经对JavaScript中的作用域和上下文做了一些阅读,但还没能突破它,因为我在集成开发环境中看不到它。
如果需要的话,我很乐意提供更多的信息。
发布于 2012-11-28 01:59:59
这很好用,只需调整您的范围并设置原型搜索即可:
Context cx = Context.enter();
try {
// Cache and reuse:
ScriptableObject sealedSharedScope = cx.initStandardObjects(null,
true);
// Force the LiveConnect stuff to be loaded.
String loadMe = "RegExp; getClass; java; Packages; JavaAdapter;";
cx.evaluateString(sealedSharedScope, loadMe, "preLoadLazyLoad", 0,
null);
cx.evaluateString(sealedSharedScope, "varInRoot = 'blah';",
"setVarInRoot", 0, null);
// here you can put more cx.evaluateString calls to set up your
// environment (eg. hmTCResult)
// now connect a throw-away new scope into the hierarchy, with local
// vars:
Scriptable scope = cx.newObject(sealedSharedScope);
// ensure that definitions in the root scope are found
scope.setPrototype(sealedSharedScope);
// ensure that new global variables are created in this scope (don't
// use
// var for them!)
scope.setParentScope(null);
cx.evaluateString(scope, "localVar = varInRoot;", "mySource", 0,
null);
assertEquals("blah", scope.get("localVar", scope).toString());
// new var not in root:
assertEquals(ScriptableObject.NOT_FOUND,
sealedSharedScope.get("localVar", scope));
} finally {
Context.exit();
}注意,scope.get不会搜索原型链--必须自己搜索!
作用域独立于上下文,并且幸存于Context.exit()。
发布于 2012-10-23 05:41:43
要在Java中评估js脚本,可以执行以下操作
ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType( "text/javascript" );
Bindings bindings = engine.getBindings( ScriptContext.GLOBAL_SCOPE );
bindings.put( "varname", ... );
bindings.put( ... );
engine.put( ScriptEngine.FILENAME, script.toString());
engine.eval( new FileReader( script ));如果这3个脚本是在相同的引擎/绑定中加载的,这是可以的,但如果引擎是新分配来执行script3的,则上下文已被清除。
这篇文章不是真正的答案,但太长了,不能作为评论。
发布于 2012-11-22 06:18:33
我的猜测是,在没有更多信息的情况下,假设您修改后的脚本是绝对正确的,那么您的脚本将在单独的作用域中运行,所有的全局作用域都作为父作用域。
因此,我猜测changeStatus之所以能在第三个脚本中工作,是因为没有对它进行var声明。因此,如果没有其他配置,它将被定义为顶级或全局作用域中的一个变量,该变量在三个脚本之间共享。
我的猜测是,hmTCResult不工作的原因是用关键字var声明的,该关键字表示一个局部变量。如果所有脚本都在顶级作用域中运行,这将在全局对象上定义一个变量。但是如果每个脚本都在自己的作用域中运行,这将只在脚本1的作用域中定义一个变量。您不会在脚本2的作用域中看到这个问题,因为在脚本3执行之前,没有人会执行脚本2中的代码。
https://stackoverflow.com/questions/12999095
复制相似问题