Kotlin 語言中調(diào)用 JavaScript 方法實例詳解
Kotlin 語言中調(diào)用 JavaScript 方法實例詳解
Kotlin 已被設(shè)計為能夠與 Java 平臺輕松互操作。它將 Java 類視為 Kotlin 類,并且 Java 也將 Kotlin 類視為 Java 類。但是,JavaScript 是一種動態(tài)類型語言,這意味著它不會在編譯期檢查類型。你可以通過動態(tài)類型在 Kotlin 中自由地與 JavaScript 交流,但是如果你想要 Kotlin 類型系統(tǒng)的全部威力 ,你可以為 JavaScript 庫創(chuàng)建 Kotlin 頭文件。
內(nèi)聯(lián) JavaScript
你可以使用 js("……") 函數(shù)將一些 JavaScript 代碼嵌入到 Kotlin 代碼中。 例如:
fun jsTypeOf(o: Any): String {
return js("typeof o")
}
js 的參數(shù)必須是字符串常量。因此,以下代碼是不正確的:
fun jsTypeOf(o: Any): String {
return js(getTypeof() + " o") // 此處報錯
}
fun getTypeof() = "typeof"
external 修飾符
要告訴 Kotlin 某個聲明是用純 JavaScript 編寫的,你應(yīng)該用 external 修飾符來標(biāo)記它。 當(dāng)編譯器看到這樣的聲明時,它假定相應(yīng)類、函數(shù)或?qū)傩缘膶崿F(xiàn)由開發(fā)人員提供,因此不會嘗試從聲明中生成任何 JavaScript 代碼。 這意味著你應(yīng)該省略 external 聲明內(nèi)容的代碼體。例如:
external fun alert(message: Any?): Unit
external class Node {
val firstChild: Node
fun append(child: Node): Node
fun removeChild(child: Node): Node
// 等等
}
external val window: Window
請注意,嵌套的聲明會繼承 external 修飾符,即在 Node 類中,我們在成員函數(shù)和屬性之前并不放置 external。
external 修飾符只允許在包級聲明中使用。 你不能聲明一個非 external 類的 external 成員。
聲明類的(靜態(tài))成員
在 JavaScript 中,你可以在原型或者類本身上定義成員。即:
function MyClass() {
}
MyClass.sharedMember = function() { /* 實現(xiàn) */ };
MyClass.prototype.ownMember = function() { /* 實現(xiàn) */ };
Kotlin 中沒有這樣的語法。然而,在 Kotlin 中我們有伴生(companion)對象。Kotlin 以特殊的方式處理external 類的伴生對象:替代期待一個對象的是,它假定伴生對象的成員就是該類自身的成員。要描述來自上例中的 MyClass,你可以這樣寫:
external class MyClass {
companion object {
fun sharedMember()
}
fun ownMember()
}
聲明可選參數(shù)
一個外部函數(shù)可以有可選參數(shù)。 JavaScript 實現(xiàn)實際上如何計算這些參數(shù)的默認(rèn)值,是 Kotlin 所不知道的, 因此在 Kotlin 中不可能使用通常的語法聲明這些參數(shù)。 你應(yīng)該使用以下語法:
external fun myFunWithOptionalArgs(x: Int, y: String = definedExternally, z: Long = definedExternally)
這意味著你可以使用一個必需參數(shù)和兩個可選參數(shù)來調(diào)用 myFunWithOptionalArgs(它們的默認(rèn)值由一些 JavaScript 代碼算出)。
擴展 JavaScript 類
你可以輕松擴展 JavaScript 類,因為它們是 Kotlin 類。只需定義一個 external 類并用非 external 類擴展它。例如:
external open class HTMLElement : Element() {
/* 成員 */
}
class CustomElement : HTMLElement() {
fun foo() {
alert("bar")
}
}
有一些限制:
當(dāng)一個外部基類的函數(shù)被簽名重載時,不能在派生類中覆蓋它。
不能覆蓋一個使用默認(rèn)參數(shù)的函數(shù)。
請注意,你無法用外部類擴展非外部類。
external 接口
JavaScript 沒有接口的概念。當(dāng)函數(shù)期望其參數(shù)支持 foo 和 bar 方法時,只需傳遞實際具有這些方法的對象。 對于靜態(tài)類型的 Kotlin,你可以使用接口來表達這點,例如:
external interface HasFooAndBar {
fun foo()
fun bar()
}
external fun myFunction(p: HasFooAndBar)
外部接口的另一個使用場景是描述設(shè)置對象。例如:
external interface JQueryAjaxSettings {
var async: Boolean
var cache: Boolean
var complete: (JQueryXHR, String) -> Unit
// 等等
}
fun JQueryAjaxSettings(): JQueryAjaxSettings = js("{}")
external class JQuery {
companion object {
fun get(settings: JQueryAjaxSettings): JQueryXHR
}
}
fun sendQuery() {
JQuery.get(JQueryAjaxSettings().apply {
complete = { (xhr, data) ->
window.alert("Request complete")
}
})
}
外部接口有一些限制:
它們不能在 is 檢查的右側(cè)使用。
as 轉(zhuǎn)換為外部接口總是成功(并在編譯時產(chǎn)生警告)。
它們不能作為具體化類型參數(shù)傳遞。
它們不能用在類的字面值表達式(即 I::class)中。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
詳解Java多線程編程中互斥鎖ReentrantLock類的用法
Java多線程并發(fā)的程序中使用互斥鎖有synchronized和ReentrantLock兩種方式,這里我們來詳解Java多線程編程中互斥鎖ReentrantLock類的用法:2016-07-07
解決idea找不到類could not find artifact問題
本文總結(jié)了解決Java項目中找不到類的問題的常見解決方案,包括刷新Maven項目、清理IDEA緩存、Maven Clean Install、重新Package、解決依賴沖突和手動導(dǎo)入依賴包等方法2025-01-01
Java實現(xiàn)并發(fā)執(zhí)行定時任務(wù)并手動控制開始結(jié)束
這篇文章主要介紹了Java實現(xiàn)并發(fā)執(zhí)行定時任務(wù)并手動控制開始結(jié)束,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05
JavaIO?BufferedReader和BufferedWriter使用及說明
這篇文章主要介紹了JavaIO?BufferedReader和BufferedWriter使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12

