我正试图从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()?
答案 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”。