官方文檔: http://kotlinlang.org/docs/reference/js-interop.html
1.Kotlin調用JavaScript(Calling JavaScript from Kotlin)
Kotlin被設計能夠與Java平臺輕鬆互操作,kotlin可將Java類轉爲Kotlin類,Java也將Kotlin類轉爲Java類!
但JavaScript是一種動態類型語言,意味着不會在編譯期檢查類型,可以在Kotlin中與JavaScript自由交流,
但如果想用Kotlin類型系統全部功能,需要在JavaScript庫創建Kotlin頭文件!
2.內聯JavaScript(Inline JavaScript)
可用js("JavaScript代碼")函數將JavaScript代碼嵌入到Kotlin代碼中:
fun jsTypeOf(o: Any): String {
return js("typeof o")
}
js("...")函數參數必須是字符串常量,因此以下代碼錯誤:
fun jsTypeOf(o: Any): String {
return js(getTypeof() + " o") // 此處報錯
}
fun getTypeof() = "typeof"
3.external修飾符(external modifier)
用external修飾符來標記,通知Kotlin某個聲明是用純JavaScript編寫!
編譯器會認爲被修飾的類/函數/屬性的具體實現由開發人員提供,不會在聲明中生成任何JavaScript代碼,
因此external聲明應該沒有代碼體內容,例如:
// 以下聲明都沒有代碼體,具體代碼由JavaScript提供
external fun alert(message: Any?): Unit
external val window: Window
external class Node {
//external修飾符會被繼承,即Node類的成員函數和屬性前不需要添加external
val firstChild: Node
fun append(child: Node): Node
fun removeChild(child: Node): Node
}
提示: external修飾符只允許在包級聲明中使用(package-level)
4.聲明類的靜態成員(Declaring static members)
在JavaScript中可以在原型(prototype)或者類(class)本身上定義成員:
function MyClass() {
}
MyClass.sharedMember = function() {
};
MyClass.prototype.ownMember = function() {
};
Kotlin沒有這樣的語法,但Kotlin有伴生對象(companion object),假定伴生對象的成員就是該類自身的成員:
external class MyClass {
companion object {
fun sharedMember()
}
fun ownMember()
}
5.聲明可選參數(Declaring optional parameters)
一個外部(external)函數有可選參數,但Kotlin無法知道JavaScript是如何計算這些參數的默認值,
因此在Kotlin中不能使用常用語法聲明這些默認參數,應該使用以下語法:
external fun myFunWithOptionalArgs(x: Int,
y: String = definedExternally,
z: Long = definedExternally)
// y, z 參數默認值由JavaScript代碼算出(definedExternally在外部定義)
6.擴展JavaScript類(Extending JavaScript class)
擴展JavaScript類很容易,因爲它們都是Kotlin類,只需定義一個external類,並用非external類擴展,例如:
external open class HTMLElement : Element() {
}
class CustomElement : HTMLElement() {
fun foo() {
alert("bar")
}
}
一些限制:
1.當一個外部(external)基類的函數被簽名重載時,不能在派生類(子類)中覆蓋它;
2.不能覆蓋一個使用默認參數的函數;
注意: 不能用external類擴展非external類!
7.external接口(external interface)
JavaScript沒有接口的概念,當函數期望其參數支持方法時,只能傳遞含有這些方法的對象;
對於靜態類型的Kotlin,可以使用外部(external)接口,例如:
external interface HasFooAndBar {
fun foo()
fun bar()
}
// 傳遞含有foo和bar方法的HasFooAndBar
external fun myFunction(p: HasFooAndBar)
外部(external)接口的另一個使用場景是描述設置對象(settings objects),例如:
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")
}
})
}
外部(external)接口的一些限制:
1.它們不能在is檢查操作符的右側使用;
2.as轉換爲external接口總是成功(在編譯時產生警告);
3.它們不能作爲具體化類型參數(reified type)傳遞;
4.它們不能用在類的字面值(literal)表達式(例如 I::class)中;
簡書:http://www.jianshu.com/p/d7259e03bd72
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/75675844
GitHub博客: http://lioil.win/2017/07/21/Kotlin-jsInKotlin.html
Coding博客: http://c.lioil.win/2017/07/21/Kotlin-jsInKotlin.html