Kotlin 語(yǔ)言中調(diào)用 JavaScript 方法實(shí)例詳解
Kotlin 語(yǔ)言中調(diào)用 JavaScript 方法實(shí)例詳解
Kotlin 已被設(shè)計(jì)為能夠與 Java 平臺(tái)輕松互操作。它將 Java 類視為 Kotlin 類,并且 Java 也將 Kotlin 類視為 Java 類。但是,JavaScript 是一種動(dòng)態(tài)類型語(yǔ)言,這意味著它不會(huì)在編譯期檢查類型。你可以通過(guò)動(dòng)態(tài)類型在 Kotlin 中自由地與 JavaScript 交流,但是如果你想要 Kotlin 類型系統(tǒng)的全部威力 ,你可以為 JavaScript 庫(kù)創(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") // 此處報(bào)錯(cuò)
}
fun getTypeof() = "typeof"
external 修飾符
要告訴 Kotlin 某個(gè)聲明是用純 JavaScript 編寫的,你應(yīng)該用 external 修飾符來(lái)標(biāo)記它。 當(dāng)編譯器看到這樣的聲明時(shí),它假定相應(yīng)類、函數(shù)或?qū)傩缘膶?shí)現(xiàn)由開發(fā)人員提供,因此不會(huì)嘗試從聲明中生成任何 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
請(qǐng)注意,嵌套的聲明會(huì)繼承 external 修飾符,即在 Node 類中,我們?cè)诔蓡T函數(shù)和屬性之前并不放置 external。
external 修飾符只允許在包級(jí)聲明中使用。 你不能聲明一個(gè)非 external 類的 external 成員。
聲明類的(靜態(tài))成員
在 JavaScript 中,你可以在原型或者類本身上定義成員。即:
function MyClass() {
}
MyClass.sharedMember = function() { /* 實(shí)現(xiàn) */ };
MyClass.prototype.ownMember = function() { /* 實(shí)現(xiàn) */ };
Kotlin 中沒(méi)有這樣的語(yǔ)法。然而,在 Kotlin 中我們有伴生(companion)對(duì)象。Kotlin 以特殊的方式處理external 類的伴生對(duì)象:替代期待一個(gè)對(duì)象的是,它假定伴生對(duì)象的成員就是該類自身的成員。要描述來(lái)自上例中的 MyClass,你可以這樣寫:
external class MyClass {
companion object {
fun sharedMember()
}
fun ownMember()
}
聲明可選參數(shù)
一個(gè)外部函數(shù)可以有可選參數(shù)。 JavaScript 實(shí)現(xiàn)實(shí)際上如何計(jì)算這些參數(shù)的默認(rèn)值,是 Kotlin 所不知道的, 因此在 Kotlin 中不可能使用通常的語(yǔ)法聲明這些參數(shù)。 你應(yīng)該使用以下語(yǔ)法:
external fun myFunWithOptionalArgs(x: Int, y: String = definedExternally, z: Long = definedExternally)
這意味著你可以使用一個(gè)必需參數(shù)和兩個(gè)可選參數(shù)來(lái)調(diào)用 myFunWithOptionalArgs(它們的默認(rèn)值由一些 JavaScript 代碼算出)。
擴(kuò)展 JavaScript 類
你可以輕松擴(kuò)展 JavaScript 類,因?yàn)樗鼈兪?Kotlin 類。只需定義一個(gè) external 類并用非 external 類擴(kuò)展它。例如:
external open class HTMLElement : Element() {
/* 成員 */
}
class CustomElement : HTMLElement() {
fun foo() {
alert("bar")
}
}
有一些限制:
當(dāng)一個(gè)外部基類的函數(shù)被簽名重載時(shí),不能在派生類中覆蓋它。
不能覆蓋一個(gè)使用默認(rèn)參數(shù)的函數(shù)。
請(qǐng)注意,你無(wú)法用外部類擴(kuò)展非外部類。
external 接口
JavaScript 沒(méi)有接口的概念。當(dāng)函數(shù)期望其參數(shù)支持 foo 和 bar 方法時(shí),只需傳遞實(shí)際具有這些方法的對(duì)象。 對(duì)于靜態(tài)類型的 Kotlin,你可以使用接口來(lái)表達(dá)這點(diǎn),例如:
external interface HasFooAndBar {
fun foo()
fun bar()
}
external fun myFunction(p: HasFooAndBar)
外部接口的另一個(gè)使用場(chǎng)景是描述設(shè)置對(duì)象。例如:
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)換為外部接口總是成功(并在編譯時(shí)產(chǎn)生警告)。
它們不能作為具體化類型參數(shù)傳遞。
它們不能用在類的字面值表達(dá)式(即 I::class)中。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
SpringBoot異步與事務(wù)一起使用的問(wèn)題解決
本文主要介紹了SpringBoot異步與事務(wù)一起使用的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
java中對(duì)HashMap的put過(guò)程解讀
這篇文章主要介紹了java中對(duì)HashMap的put過(guò)程解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法
這篇文章主要介紹了Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文大家能掌握理解這種方法,需要的朋友可以參考下2017-09-09
spring boot 統(tǒng)一JSON格式的接口返回結(jié)果的實(shí)現(xiàn)
這篇文章主要介紹了spring boot 統(tǒng)一JSON格式的接口返回結(jié)果的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)配置
Flayway是一款數(shù)據(jù)庫(kù)版本控制管理工具,支持?jǐn)?shù)據(jù)庫(kù)版本自動(dòng)升級(jí),Migrations可以寫成sql腳本,也可以寫在java代碼里;本文通過(guò)實(shí)例代碼給大家介紹springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)過(guò)程,感興趣的朋友一起看看吧2021-06-06
Java實(shí)現(xiàn)把窗體隱藏到系統(tǒng)托盤方法
這篇文章主要介紹了Java實(shí)現(xiàn)把窗體隱藏到系統(tǒng)托盤方法,本文直接給出核心功能代碼,需要的朋友可以參考下2015-05-05
Java利用ITextPdf庫(kù)生成PDF預(yù)覽文件的具體實(shí)現(xiàn)
這篇文章主要給大家介紹了Java利用ITextPdf庫(kù)生成PDF預(yù)覽文件的具體實(shí)現(xiàn),文中通過(guò)代碼示例和圖文給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-04-04

