JavaScript 中调用 Kotlin

    为了防止损坏全局对象,Kotlin 创建一个包含当前模块中所有 Kotlin 声明的对象。所以如果你把模块命名为 ,那么所有的声明都可以通过 myModule 对象在 JavaScript 中可用。例如:

    可以在 JavaScript 中这样调用:

    1. alert(myModule.foo());

    这不适用于当你将 Kotlin 模块编译为 JavaScript 模块时(关于这点的详细信息请参见 JavaScript 模块)。在这种情况下,不会有一个包装对象,而是将声明作为相应类型的 JavaScript 模块对外暴露。例如,对于 CommonJS 的场景,你应该写:

    Kotlin 将其包结构暴露给 JavaScript,因此除非你在根包中定义声明,否则必须在 JavaScript 中使用完整限定的名称。例如:

    1. package my.qualified.packagename
    2. fun foo() = "Hello"

    在某些情况下(例如为了支持重载),Kotlin 编译器会修饰(mangle) JavaScript 代码中生成的函数和属性的名称。要控制生成的名称,可以使用 注解:

    1. // 模块“kjs”
    2. class Person(val name: String) {
    3. }
    4. @JsName("helloWithGreeting")
    5. fun hello(greeting: String) {
    6. println("$greeting $name!")
    7. }
    8. }

    现在,你可以通过以下方式在 JavaScript 中使用这个类:

    如果我们没有指定 注解,相应函数的名称会包含从函数签名计算而来的后缀,例如 hello_61zpoe$

    请注意,Kotlin 编译器不会对 external 声明应用这种修饰,因此你不必在其上使用 @JsName。 值得注意的另一个例子是从外部类继承的非外部类。在这种情况下,任何被覆盖的函数也不会被修饰。

    1. @JsName("new C()") // 此处出错
    2. external fun newC()
    • 除了 kotlin.Long 的 Kotlin 数字类型映射到 JavaScript Number。
    • kotlin.Char 映射到 JavaScript Number 来表示字符代码。

    kotlinfun f() { val x: Int = 23 val y: Any = x println(y as Float)}

    • Kotlin 保留了 kotlin.Int、 kotlin.Byte、 kotlin.Short、 kotlin.Char 和 kotlin.Long 的溢出语义。

    • JavaScript 中没有 64 位整数,所以 kotlin.Long 没有映射到任何 JavaScript 对象,它是由一个 Kotlin 类模拟的。

    • kotlin.String 映射到 JavaScript String。
    • kotlin.Any 映射到 JavaScript Object(即 new Object()、 {} 等)。
    • kotlin.Array 映射到 JavaScript Array。
    • Kotlin 集合(即 List、 Set、 Map 等)没有映射到任何特定的 JavaScript 类型。
    • kotlin.Throwable 映射到 JavaScript Error。
    • Kotlin 在 JavaScript 中保留了惰性对象初始化。
    • Kotlin 不会在 JavaScript 中实现顶层属性的惰性初始化。
      自 1.1.50 版起,原生数组转换到 JavaScript 时采用 TypedArray:

    • kotlin.BooleanArray 会映射为 JavaScript 中具有 $type$ == "BooleanArray" 属性的 Int8Array
    • kotlin.LongArray 会映射为 JavaScript 中具有 $type$ == "LongArray" 属性的 kotlin.Long 的数组。