代码之家  ›  专栏  ›  技术社区  ›  Greg

如何将此上下文与Nashorn中的invokeFunction结合起来?

  •  0
  • Greg  · 技术社区  · 7 年前

    我试图从Java/Nashorn调用Javascript中的函数(在Scala中,但这不是问题的实质)。

    // JS
    var foo = function(calculator){  // calculator is a Scala object
      return this.num * calculator.calcMult();
    }
    

    case class Thing(
      num: Int,
      stuff: String
    )
    
    case class Worker() {  // Scala object to bind to calculator
      def calMult() = { 3 }  // presumably some complex computation here
    }
    

    我首先让foo进入JS环境:

    jsengine.eval("""var foo = function(calculator){return this.num * calculator.calcMult();}"""
    

    要使用它,我需要两件事:1)“this”上下文将填充我的Thing对象,2)能够将Java/Scala对象传递给JS函数(稍后调用calcMulti)。 (如果需要,我可以轻松地JSON序列化东西。)

    如何做到这两个并成功地从Scala调用foo()?

    0 回复  |  直到 7 年前
        1
  •  0
  •   Greg    7 年前

    这可能不是唯一或最干净的解决方案,但确实有效。

    val inv = javascript.asInstanceOf[Invocable]
    val myThis: String = // JSON serialized Map of stuff you want accessible in the js function
    
    val bindFn = "bind_" + fnName
    javascript.eval(bindFn + s" = $fnName.bind(" + myThis + ")")
    
    inv.invokeFunction(bindFn, args: _*)
    

    如果你把myThis传入绑定中 {"x":"foo"} this.x 会像你所期望的那样解决问题。

    推荐文章