【问题标题】:Scala.js native Javascript constructorsScala.js 原生 Javascript 构造函数
【发布时间】:2017-02-03 04:46:36
【问题描述】:

原生 JS 类型的 Scala.js 外观可以如下所示(来自Three.js facade):

@js.native
@JSName("THREE.Vector3")
class Vector3 extends Vector {
  def this(x: Double = js.native, y: Double = js.native, z: Double = js.native) = this()
  var x: Double = js.native
  var y: Double = js.native
  var z: Double = js.native

/* ... */
}

构造Vector3的函数对应的Javascript definition为:

function Vector3( x, y, z ) {

    this.x = x || 0;
    this.y = y || 0;
    this.z = z || 0;

}

我已经阅读了有关creating Scala.js facades 的文档,但是那里只是简单地提到了构造函数。外观代码在实际代码中运行良好,但我不确定定义是否正确以及它为什么以及如何工作。

  • 外观不允许存在任何参数构造函数。
  • 带参数的构造函数只是调用无参数构造函数。对象似乎仍然构造得很好,成员设置为传递的值。
  • 构造函数使用js.native 作为所有参数的默认值。所有的门面都应该这样定义构造函数吗?

特别是。第二点让我感到困惑。这怎么行?在这三种情况下,我想知道为构造函数生成了哪些 JS 代码以及为什么。

人们也可以想象一种不同的方式来编写外观。那会更正确吗?

class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native) extends Vector {

/* ... */
}

【问题讨论】:

    标签: scala constructor scala.js


    【解决方案1】:

    定义是正确的。 JavaScript 构造函数的门面规则很简单:当遇到诸如

    这样的调用时
    new C(arg1, ..., argN)
    

    C 是一个JavaScript 类,它转换为

    new Cconstr(arg1, ..., argN)
    

    其中Cconstr 是评估js.constructorOf[C] 的结果。对于原生 JavaScript 类,js.constructorOf[C] 在全局范围内查找C 的名称(或应用@JSName@JSImport 规则)。具体来说,在您的示例中,诸如

    之类的调用
    new Vector3(3, 4, 5)
    

    翻译成

    new <global>.THREE.Vector3(3, 4, 5)
    

    请特别注意,构造函数定义的 body 是完全不相关的,因为调用站点直接调用 Three.js 库中的 JavaScript 代码。因此,语义规则完全忽略了 3-arg 构造函数调用 0-arg 构造函数并忽略其参数的事实。该调用是遵守 Scala 的类型检查规则所必需的,但在语义上无关紧要。

    同样,默认参数值的实际值在语义上是不相关的。它们的存在使参数成为可选的,但编译器会忽略它们的值。诸如

    之类的调用
    new Vector3(3)
    

    在 JavaScript 中翻译成

    new <global>.THREE.Vector3(3)
    

    其中yz参数完全没有给出,留给JavaScript来决定如何处理它们。

    最后,你的替代定义:

    class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native)
    

    同样有效。它没有显式的 0-arg 构造函数,但也可以通过向构造函数提供 0 参数来“访问”它,无论如何它都有 3 个可选参数。不过,这个定义肯定更简洁,而且看起来更像 Scala 风格,所以我个人会这样定义。但它并不比最初的更正确

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      相关资源
      最近更新 更多