我如何将此上下文与 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"。
我正在尝试从 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"。