簡體   English   中英

Scala.js本機Javascript構造函數

[英]Scala.js native Javascript constructors

原生JS類型的Scala.js外觀可以如下所示(來自Three.js外觀 ):

@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定義是:

function Vector3( x, y, z ) {

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

}

我已經閱讀了有關創建Scala.js外觀的文檔,但是構造函數只是在那里簡要提及。 外觀中的代碼在實際代碼中工作正常,但我不確定定義是否正確以及原因和工作方式。

  • facade不允許存在參數構造函數。
  • 帶參數的構造函數只調用無參數構造函數。 仍然可以將對象構造得很好,將成員設置為傳遞的值。
  • 構造函數使用js.native作為所有參數的默認值。 所有外觀是否應該以這種方式定義構造函數?

ESP。 第二點讓我感到困惑。 這怎么可行? 在所有這三種情況下,我想知道為構造函數生成什么JS代碼以及為什么。

人們還可以想象一下如何寫立面的不同方式。 那會更正確嗎?

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

/* ... */
}

定義是正確的。 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)

特別要注意,構造函數定義的主體完全不相關,因為調用站點直接調用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-esque,所以我會親自定義它。 但它不比最初的更正確

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM