【问题标题】:How to call Javascript apply() from Scala.js?如何从 Scala.js 调用 Javascript apply()?
【发布时间】:2014-08-19 10:08:47
【问题描述】:

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

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

var test = {
  apply: function(idx) {...},
  apple: function(idx) {...}
}
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

【问题讨论】:

  • 稍加注意,但如果可能,请避免调用函数apply,除非您确实想覆盖默认的apply 行为:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 感谢您的提示;但是,我不想在函数上调用 apply(),而是在对象上调用。
  • 在 JavaScript 中,对象一个函数。如果您不确定,弹出您最喜欢的控制台并输入Object instanceof Function。当然,反过来也是也是正确的。期望 JavaScript 表现得像经典的面向对象语言迟早会导致混乱。 stackoverflow.com/questions/7018023/…
  • 好吧,当我这样做时,Chrome 中的控制台会回复“TypeError: object is not a function”:test = { apply: function() {} }; test()
  • 这里test 是一个匿名对象——它确实不是一个函数——但也不能被实例化或调用,因为你已经将它声明为一个变量而不是一个对象。所以你可以调用test.apply() 但 test 是变量的名称而不是类型的名称。

标签: scala.js


【解决方案1】:

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

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

测试:

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

test.apple(1) // -> 1
test.apply(1) // -> 1

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

val dyn = test.asInstanceOf[js.Dynamic]

dyn.applyDynamicNamed("apply")(1) // -> 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2018-10-29
    • 2017-06-20
    • 2015-02-05
    • 1970-01-01
    相关资源
    最近更新 更多