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

How can I combine this context with invokeFunction in Nashorn?

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

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

Scala端的上下文是这样的:

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-序列化 Thing。)

如何同时执行这两项操作并从 Scala 成功调用 foo()?

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

事实证明 javascript 能够将给定的 'this' 上下文绑定到一个函数,这会创建一个 "bound function",其中可以看到您的 'this'。然后像往常一样在绑定函数上使用 invoke()。

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 的任何访问都将按照您的预期解析为 "foo"。