在多个nashorn脚本引擎之间共享JavaScript数组和对象

Sharing JavaScript arrays and objects between multiple nashorn ScriptEngines

本文关键字:JavaScript 共享 数组 对象 之间 引擎 nashorn 脚本      更新时间:2023-09-26

我对nashorn有问题,我不太了解原生构造函数(Object、Array等)的工作方式。

我的问题涉及到应用程序生命周期中的几个ScriptEngine,其中一些可以创建函数。

我尝试在新的ScriptEngine中使用这些函数,问题是我无法检查对象是否属于给定类型(数组实例的数组),因为该数组不是由该实例的数组构造函数生成的。

这里有一个复制它的测试:

def "Just testing"() {                                                                                                                                      
when:                                                                                                                                                     
  def manager = new ScriptEngineManager()                                                                                                                 
  def engine1 = manager.getEngineByName("nashorn")                                                                                                        
  def engine2 = manager.getEngineByName("nashorn")                                                                                                                
  def arrImpl = engine1.eval("[]")                                                                                                                        
  engine2.context.setAttribute("arr", arrImpl, ScriptContext.ENGINE_SCOPE)                                                                                
  def val = engine2.eval("arr instanceof Array")                                                                                                          
then:                                                                                                                                                     
  val == true                                                                                                                                             
}

我读过这篇文章https://wiki.openjdk.java.net/display/Nashorn/Nashorn+jsr223+engine+notes,并试图这样解决它,但仍然没有运气

def "Just testing"() {                                                                                                                                      
when:                                                                                                                                                     
  def manager = new ScriptEngineManager()                                                                                                                 
  def engine1 = manager.getEngineByName("nashorn")                                                                                                        
  def engine2 = manager.getEngineByName("nashorn")                                                                                                        
  def context = new SimpleScriptContext()                                                                                                                 
  def bindings = engine1.getContext().getBindings(ScriptContext.ENGINE_SCOPE)                                                                             
  context.setBindings(bindings, ScriptContext.ENGINE_SCOPE)                                                                                                              
  def arrImpl = engine1.eval("[]")                                                                                                                        

  context.setAttribute("arr", arrImpl, ScriptContext.ENGINE_SCOPE)                                                                                        
  def val = engine2.eval("arr instanceof Array", context)                                                                                                 
then:                                                                                                                                                     
  val == true                                                                                                                                             
}

你知道如何使它发挥作用吗?

每个引擎的engine_SCOPE绑定都与一个Nashorn全局作用域对象相关联。"Array"、"Object"等是在全局范围内定义的JS内置构造函数。因此,这些构造函数在不同的全局范围内是不同的。所以,您不能将来自另一个全局范围的对象与"instanceof"进行比较。但由于基于智能动态链接的链接,nashorn仍然可以允许您访问此类"跨全局"对象的属性。例如,您可以使用正常的属性/元素访问、方法调用语法,从另一个引擎中运行的脚本访问"length"属性、数组元素。希望这能有所帮助。