JavaScript 中調用 Kotlin 方法實例詳解
Kotlin 編譯器生成正常的 JavaScript 類,可以在 JavaScript 代碼中自由地使用的函數和屬性 。不過,你應該記住一些微妙的事情。
用獨立的 JavaScript 隔離聲明
為了防止損壞全局對象,Kotlin 創建一個包含當前模塊中所有 Kotlin 聲明的對象 。所以如果你把模塊命名為 myModule,那么所有的聲明都可以通過 myModule 對象在 JavaScript 中可用。例如:
fun foo() = "Hello"
可以在 JavaScript 中這樣調用:
alert(myModule.foo());
這不適用于當你將 Kotlin 模塊編譯為 JavaScript 模塊時(關于這點的詳細信息請參見 JavaScript 模塊)。 在這種情況下,不會有一個包裝對象,而是將聲明作為相應類型的 JavaScript 模塊對外暴露。例如, 對于 CommonJS 的場景,你應該寫:
alert(require('myModule').foo());包結構
Kotlin 將其包結構暴露給 JavaScript,因此除非你在根包中定義聲明, 否則必須在 JavaScript 中使用完整限定的名稱。例如:
package my.qualified.packagenamefun foo() = "Hello"
可以在 JavaScript 中這樣調用:
alert(myModule.my.qualified.packagename.foo());
@JsName 注解
在某些情況下(例如為了支持重載),Kotlin 編譯器會修飾(mangle) JavaScript 代碼中生成的函數和屬性的名稱。要控制生成的名稱,可以使用 @JsName 注解:
// 模塊“kjs”class Person(val name: String) { fun hello() { println("Hello $name!") } @JsName("helloWithGreeting") fun hello(greeting: String) { println("$greeting $name!") }}現在,你可以通過以下方式在 JavaScript 中使用這個類:
var person = new kjs.Person("Dmitry"); // 引用到模塊“kjs”person.hello(); // 輸出“Hello Dmitry!”person.helloWithGreeting("Servus"); // 輸出“Servus Dmitry!”如果我們沒有指定 @JsName 注解,相應函數的名稱會包含從函數簽名計算而來的后綴,例如 hello_61zpoe$。
請注意,Kotlin 編譯器不會對 external 聲明應用這種修飾,因此你不必在其上使用 @JsName。 值得注意的另一個例子是從外部類繼承的非外部類。 在這種情況下,任何被覆蓋的函數也不會被修飾。
@JsName 的參數需要是一個常量字符串字面值,該字面值是一個有效的標識符。 任何嘗試將非標識符字符串傳遞給 @JsName 時,編譯器都會報錯。 以下示例會產生編譯期錯誤:
@JsName("new C()") // 此處出錯external fun newC()在 JavaScript 中表示 Kotlin 類型
fun f() { val x: Int = 23 val y: Any = x println(y as Float)}感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
新聞熱點
疑難解答