关于Nashorn的问题 - JSObject

时间:2015-10-31 21:47:22

标签: java nashorn jsobject

我想创建一个JSObject并用属性(类似于HashMap)填充它,但是没有强制转换eval(“({})”的结果,因为我认为不断评估这样的事情会真的对性能有影响。有办法吗?

1 个答案:

答案 0 :(得分:2)

如果你想使用像Maps这样的脚本对象,你也可以使用Nashorn脚本中的java.util.HashMap实例!除了支持通常的java方法调用之外,Nashorn的链接器特殊情况java.util.Map实例并支持key-as-property name idiom。这比使用Javascript对象作为Map更有效。

$ jjs
jjs> var m = new java.util.HashMap
jjs> m.foo = "bar"
bar
jjs> m.foo
bar
jjs> m.get("foo")
bar
jjs> m.put("js", "nashorn")
null
jjs> m.js
nashorn

但是,如果你坚持使用JS-object-as-map,那么你可以执行eval并转换为你提到的JSObject。您可能想要测量性能。在进行任何进一步的更改之前命中(假设!)!

你也可以掌握JS" Object"构造函数对象和'缓存'它用于从Java代码重复创建对象。然后,您可以在其上调用newObject()方法来创建一个新的空对象。

import javax.script.*;
import jdk.nashorn.api.scripting.JSObject;

public class Main {
   public static void main(String[] args) throws Exception {
      ScriptEngineManager m = new ScriptEngineManager();
      ScriptEngine e = m.getEngineByName("nashorn");

      // get JS "Object" constructor object
      JSObject objConstructor = (JSObject)e.eval("Object");

      // call 'newObject' on Object constructor
      JSObject jsObj = (JSObject) objConstructor.newObject();

      // fill properties of the new empty script object
      jsObj.setMember("foo", "bar");

      // expose the new JS object as global var!
      e.put("obj", jsObj);

      // print the object as a JSON string
      e.eval("print(JSON.stringify(obj))");
   }
}

请注意,上述方案也适用于任何用户定义的构造函数。例如。如果要使用特定的用户定义构造函数创建对象,则只需替换

  JSObject objConstructor = (JSObject)e.eval("Object");

  JSObject objConstructor = (JSObject)e.eval("MyConstructorFunc");

(假设你以前用eval代码来定义MyConstructorFunc函数)。 其余代码与上面相同。