【问题标题】:arguments.callee in scala.jsscala.js 中的 arguments.callee
【发布时间】:2014-12-02 16:45:41
【问题描述】:

我正在将此 JavaScript 函数移植到 Scala.js:

once: function (el, type, callback) {
  var typeArray = type.split(' ');
  for (var i = typeArray.length - 1; i >= 0; i--) {
    el.addEventListener(typeArray[i], function(e) {
      e.target.removeEventListener(e.type, arguments.callee);
      return callback(e);
    });
  };
},

这是我编写 Scala 代码的尝试:

def once(element: TopNode, tpe: String, callback: Function1[Event,Any]): Unit = {
  tpe.split(" ").foreach(item => element.addEventListener(item, (e : Event) => {
    e.target.removeEventListener(e.`type`, ?) // <-- what do I put here?
    callback(e)
  }))
}

如何在该占位符中引用我的 lambda?

【问题讨论】:

    标签: scala.js


    【解决方案1】:

    Scala.js 没有 JavaScript 的 arguments.callee 等效项。更一般地说,它没有 arguments 的等价物。因此 lambda 无法读取对自身的引用,除非它是通过其捕获的环境提供给它的。这可以通过在 once 方法中将 lambda 存储在 val 中来实现。理想情况下,人们想这样写:

    def once(element: TopNode, tpe: String,
        callback: Function1[Event,Any]): Unit = {
      val cb: js.Function1[Event, Any] = { (e: Event) =>
        e.target.removeEventListener(e.`type`, cb) // using cb here
        callback(e)
      }
      tpe.split(" ").foreach(item => element.addEventListener(item, cb))
    }
    

    但是,这不会编译,因为您不能在其定义的右侧使用 val(此处为 cb),即使它恰好位于 lambda 中。尝试这样做会导致以下编译错误:

    Main.scala:17: error: forward reference extends over definition of value cb
          e.target.removeEventListener(e.`type`, cb) // using cb here
    

    不过有一个简单的解决方案:改用lazy val

    def once(element: TopNode, tpe: String,
        callback: Function1[Event,Any]): Unit = {
      lazy val cb: js.Function1[Event, Any] = { (e: Event) =>
        e.target.removeEventListener(e.`type`, cb) // using cb here
        callback(e)
      }
      tpe.split(" ").foreach(item => element.addEventListener(item, cb))
    }
    

    确保将cb 声明为js.Function1,而不是Function1。否则cb本身会引用Scala函数,而不是自动转换产生的JS函数(具有不同的身份)。您必须确保cb 指的是JS 函数。

    小提琴:http://www.scala-js-fiddle.com/gist/2b848e2f01e7af522dc1

    【讨论】:

      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多