简体   繁体   English

关于Nashorn的问题-JSObject

[英]Questions about Nashorn - JSObject

I want to create a JSObject and fill it with properties (kind of like a HashMap), but without casting the result of an eval("({})"), because I would think that constantly evaluating such a thing would really have an impact on performance. 我想创建一个JSObject并用属性(有点像HashMap)填充它,但不强制转换eval(“({{})”)的结果,因为我认为不断评估这样的事情确实会产生对性能的影响。 Is there a way? 有办法吗?

If you want to use script objects like Maps, you might as well use java.util.HashMap instances from Nashorn scripts! 如果要使用诸如Maps之类的脚本对象,则最好使用Nashorn脚本中的java.util.HashMap实例! In addition to supporting the usual java method calls, Nashorn's linker special cases java.util.Map instances and supports keys-as-property names idiom. 除了支持常规的Java方法调用外,Nashorn的链接器还特殊使用java.util.Map实例,并支持键值作为属性的成语。 This is more efficient than using a Javascript object as a Map. 这比使用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

But, if you insist on using JS-object-as-map, then you can do the eval and cast to JSObject you mentioned. 但是,如果您坚持使用JS-object-as-map,则可以进行评估并转换为您提到的JSObject。 You may want to measure the perf. 您可能要测量性能。 hit (which is assumed!) before making any further changes! 进行任何进一步的更改之前,请先按(假定!)!

You can also get hold of JS "Object" constructor object and 'cache' it for repeated object creation from Java code. 您还可以获取JS“对象”构造函数对象,并对其进行“缓存”,以便通过Java代码重复创建对象。 You can then call newObject() method on it to create a new empty object. 然后,可以对其调用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))");
   }
}

Note that the above scheme works for any user-defined constructor function as well. 请注意,以上方案也适用于任何用户定义的构造函数。 For eg. 例如。 if you want to create objects using specific user defined constructor function, you just have to replace 如果要使用特定的用户定义的构造函数创建对象,则只需替换

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

with

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

(assuming you've eval'ed code to define MyConstructorFunc function earlier). (假设您已经评估过代码以更早地定义MyConstructorFunc函数)。 The rest of the code is same as above. 其余代码与上面相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM