如何从Scala.js调用Javascript apply()?

jok*_*ade 5 scala.js

如何apply()从Scala.js代码调用Javascript对象上定义的函数?

显而易见的解决方案不起作用,因为applyScala.JS(?)总是将其编译到其父对象的函数调用中:

var test = {
  apply: function(idx) {...},
  apple: function(idx) {...}
}
Run Code Online (Sandbox Code Playgroud)
trait Test extends js.Object {
  def apple(idx: Int) : Int = ???
  def apply(idx: Int) : Int = ???
}

val test = js.Dynamic.global.test.asInstanceOf[Test]

test.apple(1) // works, of course

test.apply(1) // does not work (seems to be compiled into the call test(1) ?)

js.Dynamic.global.test.apply(1) // does not work either
Run Code Online (Sandbox Code Playgroud)

gzm*_*zm0 5

您可以使用apply外观类型注释方法@JSName("apply").这将产生所需的行为:

trait Test extends js.Object {
  def apple(idx: Int) : Int = ???
  @JSName("apply")
  def apply(idx: Int) : Int = ???
}
Run Code Online (Sandbox Code Playgroud)

测试:

val test = js.Dynamic.literal(
    apply = (idx: Int) => idx,
    apple = (idx: Int) => idx
).asInstanceOf[Test]

test.apple(1) // -> 1
test.apply(1) // -> 1
Run Code Online (Sandbox Code Playgroud)

对于动态类型的情况,您必须applyDynamicNamed手动调用:

val dyn = test.asInstanceOf[js.Dynamic]

dyn.applyDynamicNamed("apply")(1) // -> 1
Run Code Online (Sandbox Code Playgroud)