#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})");
решена моя проблема. (Обратите внимание на скобки, которые отключают «блок кода»)