Kotlin-47.Kotlin调用JavaScript(Call JavaScript from Kotlin)

官方文档: 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容