如何在Nashorn中将此上下文与invokeFunction结合使用?

时间:2019-05-06 18:22:55

标签: scala nashorn

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

// 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)用我的Thing对象填充“ this”上下文,以及2)将Java / Scala对象传递给我的JS函数的能力(稍后调用calcMulti) 。 ((如果需要,我可以轻松地对事物进行JSON序列化。)

我该如何做并成功从Scala调用foo()?

1 个答案:

答案 0 :(得分:0)

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

结果证明javascript能够将给定的“ this”上下文绑定到函数,从而创建一个“绑定函数”,使您的“ 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”。