JavaScript中调用Kotlin - 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.packagename

fun 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 类型


本站所有代码下载:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"代码下载" 获取。

上一篇:Kotlin调用JavaScript下一篇:Kotlin JavaScript模块