使用 ScalaJS js.Object.defineProperty

Using ScalaJS js.Object.defineProperty

使用 ScalaJS,我需要创建一个 js.Object,其中包含一个值为函数的 属性,所以我这样做了:

@JSGlobal
class EventPropertyDescriptor(n: Int, rpt: WeatherReportBuilder) extends PropertyDescriptor() {
  this.configurable = true
  this.enumerable   = true
  this.value        = buildSlippyMap("mapDiv" + n, rpt)
  this.writable     = true
  this.get          = null
  this.set          = null
}


var onAfterRenderingHandler = Object.defineProperty(new Object(), "onAfterRendering", new EventPropertyDescriptor(counter, report))

哪里buildSlippyMapreturnsFunction0[Unit]

但这不会编译,因为据我了解,js.PropertyDescriptor 已作为特征实现,而 Scala 特征不能直接转换为 JavaScript...

我应该如何进行这里操作?

谢谢

克里斯·W

您只需在子class 中定义字段。此外,它需要是非本地 class:

class EventPropertyDescriptor(n: Int, rpt: WeatherReportBuilder) 
   extends PropertyDescriptor {
  val configurable = true
  val enumerable = true
  val value = buildSlippyMap("mapDiv" + n, rpt)
  val writable = true
}

var onAfterRenderingHandler = Object.defineProperty(new Object(), 
    "onAfterRendering", new EventPropertyDescriptor(counter, report))

虽然,你就不能这样做吗?

var onAfterRenderingHandler = new js.Object {
  val onAfterRendering = buildSlippyMap("mapDiv" + counter, report)
}

您的代码片段中的问题是您将 EventPropertyDescriptor 定义为(本机)@JSGlobal class。您实际上是在告诉编译器:"there is a class named EventPropertyDescriptor in JavaScript's global scope, that I did not write, go use that one"。事实上,您应该收到大量关于该代码段的编译器警告。

如果 PropertyDescriptor 是一个非原生的 JS 特征——它在 Scala.js 1.x 但不在 0.6.x 中,你可以写:

val onAfterRenderingHandler = js.Object.defineProperty(
    new js.Object(),
    "onAfterRendering",
    new js.PropertyDescriptor {
      configurable = true
      enumerable = true
      value = buildSlippyMap("mapDiv" + counter, report)
      writable = true
    }))

但是,由于 Scala.js 1.x 仍处于里程碑中,您可能正在使用 0.6.x,您将不得不使用更脏的路线:

val propDescriptor = js.Dynamic.literal(
    configurable = true,
    enumerable = true,
    value = buildSlippyMap("mapDiv" + counter, report),
    writable = true
).asInstanceOf[js.PropertyDescriptor]
val onAfterRenderingHandler = js.Object.defineProperty(
    new js.Object(),
    "onAfterRendering",
    propDescriptor)

另请参阅@gzm0 的回答,特别是询问您是否需要 defineProperty