Базовый объект JS {a: 1, b: 2} не поддерживается в Nashorn?

#javascript #java #java-8 #nashorn

#javascript #java #java-8 #nashorn

Вопрос:

Я был немного удивлен, когда вызвал исключение с помощью этого простого выражения в Nashorn (JDK8 от Oracle, последняя версия) :

 ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("js");
engine.eval("{a:1,b:2}");
  

Что дает

javax.script.ScriptException: Ожидалось 1:6 ; но найдено : {a:1,b: 2}; ^ в строке номер 1 в столбце номер 6 в jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470) в jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:537) в jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:524) в jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402) в jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155) в javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)

Есть идеи?

Ответ №1:

Предполагая, что эта функциональность аналогична javascript eval , вы получаете эту ошибку, потому что eval("{a:1,b:2}") вычисляется {} как блок кода, а не как литерал объекта.

 eval("{a:1,b:2}")  

Этот код эквивалентен:

 {
  a: 1,
  b: 2
}
  

В b: 2 строке выдается ошибка. Здесь, a становится помеченным оператором внутри нового {} блока. Итак, если бы вы создали объектный литерал только с одним свойством, это бы сработало.

 eval("{a:1}") // no errors  

Если вам нужен объектный литерал, присвойте его переменной

 eval("var obj = {a:1,b:2}")
console.log(obj)
  

Комментарии:

1. Да, все эти изменения верны. Моим реальным вариантом использования было оценить этот код для построения карты с ключами a и b и значениями (соответственно) 1 и 2… Что кажется сложным без взлома с помощью промежуточной переменной, такой как eval(«var obj = {a:1,b: 2}»)

2. @richetyann Как вы планируете использовать созданный объектный литерал? Чтобы использовать этот объект, вам нужно присвоить ему некоторую переменную. Я объяснил это в ответе, eval("{a:1,b:2}") создает оператор с меткой. Не объектные литералы.

3. Не совсем, на самом деле я могу использовать оцененный объект в качестве карты после вызова ((ScriptObjectMirror) o).to(Map.class )

Ответ №2:

Благодаря adiga, использующему

 ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("js");
engine.eval("({a:1,b:2})");
  

решена моя проблема. (Обратите внимание на скобки, которые отключают «блок кода»)