Kotlin 編譯器生成正常的 JavaScript 類,可以在 JavaScript 代碼中自由地使用的函數(shù)和屬性
。不過,你應(yīng)該記住一些微妙的事情。
為了防止損壞全局對象,Kotlin 創(chuàng)建一個(gè)包含當(dāng)前模塊中所有 Kotlin 聲明的對象
。所以如果你把模塊命名為 myModule
,那么所有的聲明都可以
通過 myModule
對象在 JavaScript 中可用。例如:
fun foo() = "Hello"
可以在 JavaScript 中這樣調(diào)用:
alert(myModule.foo());
這不適用于當(dāng)你將 Kotlin 模塊編譯為 JavaScript 模塊時(shí)(關(guān)于這點(diǎn)的詳細(xì)信息請參見 JavaScript 模塊)。
在這種情況下,不會(huì)有一個(gè)包裝對象,而是將聲明作為相應(yīng)類型的 JavaScript 模塊對外暴露。例如,
對于 CommonJS 的場景,你應(yīng)該寫:
alert(require('myModule').foo());
Kotlin 將其包結(jié)構(gòu)暴露給 JavaScript,因此除非你在根包中定義聲明,
否則必須在 JavaScript 中使用完整限定的名稱。例如:
package my.qualified.packagename
fun foo() = "Hello"
可以在 JavaScript 中這樣調(diào)用:
alert(myModule.my.qualified.packagename.foo());
@JsName
注解在某些情況下(例如為了支持重載),Kotlin 編譯器會(huì)修飾(mangle) JavaScript 代碼中生成的函數(shù)和屬性
的名稱。要控制生成的名稱,可以使用 @JsName
注解:
// 模塊“kjs”
class Person(val name: String) {
fun hello() {
println("Hello $name!")
}
@JsName("helloWithGreeting")
fun hello(greeting: String) {
println("$greeting $name!")
}
}
現(xiàn)在,你可以通過以下方式在 JavaScript 中使用這個(gè)類:
var person = new kjs.Person("Dmitry"); // 引用到模塊“kjs”
person.hello(); // 輸出“Hello Dmitry!”
person.helloWithGreeting("Servus"); // 輸出“Servus Dmitry!”
如果我們沒有指定 @JsName
注解,相應(yīng)函數(shù)的名稱會(huì)包含
從函數(shù)簽名計(jì)算而來的后綴,例如 hello_61zpoe$
。
請注意,Kotlin 編譯器不會(huì)對 external
聲明應(yīng)用這種修飾,因此你不必在其上
使用 @JsName
。 值得注意的另一個(gè)例子是從外部類繼承的非外部類。
在這種情況下,任何被覆蓋的函數(shù)也不會(huì)被修飾。
@JsName
的參數(shù)需要是一個(gè)常量字符串字面值,該字面值是一個(gè)有效的標(biāo)識(shí)符。
任何嘗試將非標(biāo)識(shí)符字符串傳遞給 @JsName
時(shí),編譯器都會(huì)報(bào)錯(cuò)。
以下示例會(huì)產(chǎn)生編譯期錯(cuò)誤:
@JsName("new C()") // 此處出錯(cuò)
external fun newC()
kotlin.Long
的 Kotlin 數(shù)字類型映射到 JavaScript Number。kotlin.Char
映射到 JavaScript Number 來表示字符代碼。Kotlin 在運(yùn)行時(shí)無法區(qū)分?jǐn)?shù)字類型(kotlin.Long
除外),即以下代碼能夠工作:
fun f() {
val x: Int = 23
val y: Any = x
println(y as Float)
}
Kotlin 保留了 kotlin.Int
、 kotlin.Byte
、 kotlin.Short
、 kotlin.Char
和 kotlin.Long
的溢出語義。
kotlin.Long
沒有映射到任何 JavaScript 對象,kotlin.String
映射到 JavaScript String。kotlin.Any
映射到 JavaScript Object(即 new Object()
、 {}
等)。kotlin.Array
映射到 JavaScript Array。List
、 Set
、 Map
等)沒有映射到任何特定的 JavaScript 類型。kotlin.Throwable
映射到 JavaScript Error。