将JavaScript函数编译为可调用的Java对象?

时间:2018-01-26 01:12:42

标签: javascript java nashorn scriptengine javascript-engine

假设我来了定义有效JavaScript函数的文本,如下所示:

function sum(x, y) {
    return x + y
}

我希望能够编写将该文本编译成可调用实体的Java代码,以便:

  • 我的Java代码可以发现编译的实体是函数而不是任意脚本。
  • 我的Java代码可以发现函数有多少参数
  • 我可以通过为所有参数提供数据绑定从Java调用函数。

我期待javax.script软件包提供可以实现此目的的代码,但我不能为我的生活看到如何。我将如何编写Java代码来完成我上面描述的内容。

1 个答案:

答案 0 :(得分:2)

要让Java调用JavaScript函数,首先要评估脚本,然后在全局范围内扫描函数中的变量。

您可以调用这些功能,但不能获取参数。为此,您必须自己解析函数头。

Java 8+使用Nashorn引擎。这是一个示例,有各种方法来定义函数,因此您可以看到函数头中的差异。

String script = "function sum(x, y) {\n" +
                "    return x + y\n" +
                "}\n" +
                "function diff() {\n" +
                "    return arguments[0] - arguments[1]\n" +
                "}\n" +
                "mult = function(x, y) {\n" +
                "    return x * y\n" +
                "}\n";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings vars = engine.createBindings();
engine.eval(script, vars);
for (Entry<String, Object> var : vars.entrySet()) {
    String name = var.getKey();
    Object value = var.getValue();
    if (value instanceof JSObject) {
        JSObject jsObj = (JSObject) value;
        if (jsObj.isFunction()) {
            String funcHeader = jsObj.toString().replaceFirst("(?s)\\{.*", "");
            System.out.println("function '" + name + "' defined as: " + funcHeader);
            System.out.println(name + "(5,7) = " + jsObj.call(null, 5, 7));
        }
    }
}

输出

function 'sum' defined as: function sum(x, y) 
sum(5,7) = 12.0
function 'diff' defined as: function diff() 
diff(5,7) = -2.0
function 'mult' defined as: function(x, y) 
mult(5,7) = 35.0