2015-10-31 18 views
0

我想創建一個JSObject並用屬性(類似於HashMap)填充它,但不會投射eval(「({})」)的結果,因爲我會持續不斷地評估這樣的事情會對性能產生真正的影響。有沒有辦法?關於Nashorn的問題 - JSObject

回答

2

如果您想使用像Google Maps這樣的腳本對象,那麼您最好使用Nashorn腳本中的java.util.HashMap實例!除了支持通常的java方法調用外,Nashorn的鏈接器特殊情況下的java.util.Map實例還支持keys-as-property名稱的成語。這比使用Javascript對象作爲Map更有效。但是,如果您堅持使用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("MyConstructorFunc"); 

(假設你eval'ed代碼前面定義MyConstructorFunc功能),以取代

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

。 其餘代碼與上面相同。