11

对 Nashorn 中的 ENGINE_SCOPE 和 GLOBAL_SCOPE 绑定有些困惑,尝试关注此处的讨论。

在阅读本文之前,我对范围的理解(至少在 rhino 中)是在 GLOBAL_SCOPE 中有一个共享的绑定,在 ENGINE_SCOPE 中为每个单独的引擎提供单独的绑定。然而,这个页面似乎在说每个单独的引擎都将基本的 javascript 构造存储在引擎 ENGINE_SCOPE 中存在的绑定中(混淆地称为“Nashorn 全局范围”)。这听起来像是使 GLOBAL_SCOPE 绑定实际上毫无用处(因为它们无法访问任何这些基本结构)。

我要做的是创建一个上下文,我可以将一些脚本注入其中,然后在这些脚本的上下文中反复评估不同的绑定。但是,如果我可以访问的唯一上下文是单个引擎 ENGINE_SCOPE(因为上面的任何内容都无法访问基本的 javascript 构造),那么似乎任何本地调用都必须添加到这些相同的绑定中。有谁知道如何在 Nashorn 中管理多个级别的绑定?

4

2 回答 2

2

如果在 ENGINE_SCOPE 中未找到变量,则搜索 GLOBAL_SCOPE 绑定。Nashorn 的全局对象(具有 JS Object、Number、RegExp、parseInt 等的对象)被包装为 Bindings - 这就是您的 ENGINE_SCOPE。例如。如果您将“foo”->“hello”映射条目放入 GLOBAL_SCOPE,这将在脚本中可见 - 如果 ENGINE_SCOPE 没有名为“foo”的映射条目。

于 2014-06-28T13:31:32.370 回答
-2

ENGINE_SCOPE基本上是当放入绑定的变量仅适用于该特定引擎时,而GLOBAL_SCOPE当放入绑定的变量可由同一工厂的所有引擎访问时。

是的,你是对的,如果在 中找不到任何变量,ENGINE_SCOPE它自然会在 中搜索GLOBAL_SCOPE

根据JavaDoc

static final int ENGINE_SCOPE
EngineScope 属性在单个 ScriptEngine 的生命周期内是可见的,并且为每个引擎维护一组属性。

static final int GLOBAL_SCOPE
GlobalScope 属性对同一 ScriptEngineFactory 创建的所有引擎可见。

我们可以在 Nashorn 中使用与此类似的脚本上下文来使用多个作用域

    context = new SimpleScriptContext(); // Script Context is an interface therefor you need to use an implementation of it
    context.setBindings(engine.createBindings(), SCOPE); // Set the bindings of the context, you can then use the context as an argument with the eval method of the script engine. Here engine is again an instance of javax.script.ScriptEngine
    Bindings bindings = context.getBindings(SCOPE); // Now use this for "putting" variables into the bindings SCOPE should either be ScriptContext.ENGINE_SCOPE or ScriptContext.GLOBAL_SCOPE
    bindings.put("x", "hello world");
    // Once done you must set the bindings
    context.setBindings(scope, SCOPE);
    // This code is just rough, I'm 100% sure there can always be further optimizations to this
    // Now finally evaluate your code
    engine.eval("Some pice of code..", context);   
    // Or you can use engine.setContext(YourContext) method in case you'll use your engine as an Invocable
    engine.setContext(context);
    engine.eval("Some piece of code");
    /* Do this because sometimes due to a bug you might not be able to call methods or functions from evaluated script
    Knowing about SrciptContext will help you a lot
    Note you can have multiple contexts and switch between them like I said
    Context parameter is also applicable for eval(Reader);
    */

我希望这有帮助

于 2017-05-08T13:18:38.670 回答