这可行,但我想知道是否有更合适的方法来做到这一点,或者是否确实使用绑定是正确的方法?
正如您所注意到的,当您将 Java 对象放入多语言语言时,它们在用户看来就像 Java 对象而不是 JavaScript 对象。为了使它们模仿来宾语言对象,您可以使用 Polyglot Proxy API。
JS 对象的示例(由 HashMap 支持):
try (Context context = Context.create("js")) {
Map<String, Object> backingMap = new HashMap<>();
backingMap.put("foo", "bar");
context.getBindings("js").putMember("hostObject", ProxyObject.fromMap(backingMap));
assert "bar".equals(context.eval("js", "hostObject.foo").asString());
backingMap.put("foo", "baz");
assert "baz".equals(context.eval("js", "hostObject.foo").asString());
}
JS 数组示例(由 Java 数组支持):
try (Context context = Context.create("js")) {
Object[] backingArray = new Object[42];
backingArray[0] = 42;
context.getBindings("js").putMember("hostObject", ProxyArray.fromArray(backingArray));
assert 42 == context.eval("js", "hostObject[0]").asInt();
backingArray[0] = 43;
assert 43 == context.eval("js", "hostObject[0]").asInt();
}
函数示例(由 Lambda 支持):
try (Context context = Context.create("js")) {
ProxyExecutable executable = (arguments) -> arguments[0];
context.getBindings("js").putMember("hostObject",executable);
assert 42 == context.eval("js", "hostObject(42)").asInt();
assert 43 == context.eval("js", "hostObject(43)").asInt();
}
您也可以直接实现 ProxyObject 和 ProxyArray 来自定义行为,例如,如果您想提供只读对象或数组。
这是另一个代理示例:http ://www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies
代理 Javadoc:http ://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/package-summary.html