【问题标题】:Nashorn call method of java object (passed through bindings) via function reference in JSjava对象的Nashorn调用方法(通过绑定传递)通过JS中的函数引用
【发布时间】:2023-03-28 13:25:01
【问题描述】:

我想将本机 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 java nashorn


    【解决方案1】:

    Java 方法和函数接口对象(lambda 对象)被视为脚本函数,因此可以像往常一样从 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')");
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 2011-05-11
      • 2011-12-12
      • 2012-09-07
      • 2011-04-19
      • 2012-02-03
      • 1970-01-01
      相关资源
      最近更新 更多