Я хотел бы поместить собственные объекты Java в привязки ScriptEngine для облегчения доступа.
scriptEngine.put("myApi", myApiInstance);
Здесь myApiInstance имеет один нестатический метод foo ().
Теперь в JS у меня есть функция:
someJsFunction(func) { func.call(...) }
Но звонок
someJsFunction(myApiInstance.foo)
приводит к ошибке «TypeError: func.call не является функцией».
С другой стороны, myApiInstance.foo () работает, как ожидалось. Это похоже на специфику ScripEngine, поскольку метод call () должен быть доступен в любой функции. И да, "typeof myApiInstance.foo" возвращает "function"



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Методы Java и объекты интерфейса функций (лямбда-объекты) рассматриваются как функции сценария и, следовательно, могут быть вызваны из JavaScript, как обычно. Как вы упомянули, "typeof" для таких объектов возвращает true. Вы можете вызвать их напрямую из скрипта. Но это не настоящие объекты функций JS в том смысле, что у них нет своего прототипа Function.prototype. Тем не менее, если вы хотите вызвать их с помощью Function.prototype.call или .apply [скажем, вы отправляете на любой переданный вызываемый объект), вы можете сделать следующее:
import javax.script.*;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
// get the java static method to call
e.eval("var getProp = java.lang.System.getProperty");
// direct call
e.eval("print(getProp('java.home'))");
// call using Function.prototype.call
e.eval("print(Function.prototype.call.call(getProp, null, 'java.home'))");
// a java object
e.eval("var out = java.lang.System.out");
// get an instance method
e.eval("var p = out.println");
// call java instance method using Function.prototype.call
e.eval("Function.prototype.call.call(p, out, 'hello world')");
}
}