当前位置: 首页 > 知识库问答 >
问题:

Nashorn和脚本绑定作用域

单于飞鸣
2023-03-14

对Nashorn中的ENGINE_作用域和GLOBAL_作用域绑定有点困惑,尝试跟随这里的讨论。

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

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

共有2个答案

包嘉懿
2023-03-14

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

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

根据JavaDoc

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

static final int GLOBAL_SCOPE
由同一ScriptEngineFactory创建的所有引擎都可以看到GlobalScope属性。

我们可以在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);
    */

我希望这有帮助

穆德海
2023-03-14

如果在引擎_作用域中找不到变量,则搜索全局_作用域绑定。Nashorn的全局对象(包含JS object、Number、RegExp、parseInt等的对象)被包装为绑定——这就是引擎的作用域。例如,如果你把“foo”-

 类似资料:
  • 问题内容: 我通过JSR 223使用Nashorn来执行用户输入脚本的小片段: 不同的用户脚本会调用在静态中央库(在上面的代码片段的String中保留)中定义的JavaScript函数。 每次我想获得可以从Java调用的an时,我总是不得不重新编译大型库代码。 有什么方法可以将以前编译的代码与新代码结合在一起? 问题答案: 这是由JSR-223设计的;后面真的没有代码缓存。嗯,从 理论上讲 可以,

  • 在下面的代码中,javascript运行在与主线程不同的单独线程中。该脚本是一个无限循环,因此需要以某种方式终止。怎样 使命感脚本开始运行后,cancel()不起作用。但如果我打电话。cancel()在线程初始化之后,它将终止它(注释掉的行)。

  • 变量绑定有一个作用域,并且限定在一个代码块(block)中存活(live)。代码块是一个被 {} 包围的 语句集合。另外也允许变量隐藏。 fn main() { // 此绑定存在于 main 函数中 let long_lived_binding = 1; // 这是一个代码块,比 main 函数拥有一个更小的作用域 { // 此绑定只存在于本代码块

  • 通过Java的Nashorn脚本引擎,我可以使用如下绑定在eval()的上下文中提供对象: 我希望通过提供一个默认对象来简化javascript,这样javascript就不是: 我可以写: 有没有办法做到这一点?(someMethod是对象上的方法,而不是静态方法)

  • 问题内容: 在下面的代码中,我使javascript在与主要线程不同的线程中运行。该脚本是一个无限循环,因此需要以某种方式终止。怎么样? 脚本开始运行后,调用.cancel()无效。但是,如果我在线程初始化之后立即调用.cancel(),它将终止它(注释行)。 问题答案: 与Java一样,JavaScript(在Nashorn下)也不会像Java那样在紧密循环中响应中断。该脚本需要轮询中断并自动终

  • 我正在使用Java8 Nashorn来执行一个特定的先前同意的方法。我可以毫无问题地调用特定的方法。不过困扰我的一件事是,当我加载脚本时,它也会执行它。 例如,如果file.js包含一个print("hello world!")scriptEngine.eval(new FileReader("./file.js")将执行并打印hello world。我必须先这样做,然后才能调用我想要的特定方法。