JavaScript 中调用 Kotlin 方法实例详解

作者:函数茶馆时间:2026-10-22 04:41:04浏览:629

本文详解如何在 JavaScript 中调用 Kotlin 编译生成的代码。涵盖模块隔离机制、包结构处理、@JsName 注解对函数名的控制,以及 Kotlin 类型到 JavaScript 类型的映射规则,包括数字、字符串、集合及惰性初始化的行为差异。

JavaScript 中调用 Kotlin 方法实例详解

JavaScript 中调用 Kotlin 方法实例详解

Kotlin 编译器会生成标准的 JavaScript 类,其中的函数和属性可在 JavaScript 代码中直接使用。不过,开发者需要注意一些细微的差异和限制。

使用独立的 JavaScript 隔离声明

使用独立的 JavaScript 隔离声明

为避免污染全局对象,Kotlin 会创建一个包含当前模块内所有声明的对象。若将模块命名为 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 注解

@JsName 注解

在某些情况下(例如为了支持重载),Kotlin 编译器会对生成的 JavaScript 函数和属性名称进行修饰(mangle)。若要控制生成的名称,可以使用 @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 类型

在 JavaScript 中表示 Kotlin 类型

  1. 除了 kotlin.Long 的 Kotlin 数字类型映射到 JavaScript Number。
  2. kotlin.Char 映射到 JavaScript Number 来表示字符代码。
  3. Kotlin 在运行时无法区分数字类型(kotlin.Long 除外),即以下代码能够工作:

fun f() {
  val x: Int = 23
  val y: Any = x
  println(y as Float)
}
  1. Kotlin 保留了 kotlin.Int、 kotlin.Byte、 kotlin.Short、 kotlin.Char 和 kotlin.Long 的溢出语义。
  2. JavaScript 中没有 64 位整数,所以 kotlin.Long 没有映射到任何 JavaScript 对象, 它是由一个 Kotlin 类模拟的。
  3. kotlin.String 映射到 JavaScript String。
  4. kotlin.Any 映射到 JavaScript Object(即 new Object()、 {} 等)。
  5. kotlin.Array 映射到 JavaScript Array。
  6. Kotlin 集合(即 List、 Set、 Map 等)没有映射到任何特定的 JavaScript 类型。
  7. kotlin.Throwable 映射到 JavaScript Error。
  8. Kotlin 在 JavaScript 中保留了惰性对象初始化。
  9. Kotlin 不会在 JavaScript 中实现顶层属性的惰性初始化。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

作者最新文章