[英]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外觀的文檔,但是構造函數只是在那里簡要提及。 外觀中的代碼在實際代碼中工作正常,但我不確定定義是否正確以及原因和工作方式。
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)
其中y
和z
參數完全沒有給出,留給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.