如何在Kotlin中定义全局js函数?

8
在KotlinJs项目中,我创建的每个函数和变量都会进入一个模块。但我需要在全局范围内定义一些函数。
我使用p5js库(纯JS),它允许用户在全局范围内定义事件处理函数。我正在尝试在此项目中使用KotlinJS,但我不知道如何创建全局函数来处理p5js的事件。我的所有Kotlin函数都在模块内部,为了调用我的Kotlin代码,我需要指定完整名称mymodule.draw() 目前,我必须添加一层纯JS代码,其中包含全局函数,将执行转换为Kotlin函数,如下所示:
function setup() {
    mymodule.setup();
}

function draw() {
    mymodule.draw();
}

这种方法的问题在于有很多样板和重复的代码。

1
看起来这是一个非传统的用例,当库调用您的代码时,必须将其塑造为全局范围内的函数。在我看来,Kotlin 应该坚持生成惯用的 JS 模块,简单的 JS 粘合层是最好的选择。让 JS 适应 Kotlin 比让 Kotlin 适应 JS 更容易。 - kzm
1
看起来有一种实例模式,你不需要拥有全局函数。 - kzm
3个回答

11

如果对某人有用的话,我这里还有一个解决方法:

import kotlin.browser.window

fun main() {
    window.asDynamic()["setup"] = ::setup
    window.asDynamic()["draw"] = ::draw
}

fun setup() {}
fun draw() {}

它的实际作用是,在Kotlin模块中创建函数,然后将它们分配给window对象,从而使它们成为全局函数。

这个解决方案仍然不完美,因为每个函数都需要手动分配。至少在Kotlin项目中执行正确操作,不需要维护单独的纯JS文件。 也许可以创建一个注释,并利用Kotlin反射(不知道它在KotlinJS中如何支持)。

虽然这个解决方案对我有用,但我也希望像@JsNonModule external函数一样,能够有一些开箱即用的解决方案。


3

在 Sergey 的回答基础上,当处理像 p5.js 这样的库时,也可以使用这个解决方法。

fun main() {
    window.asDynamic().setup = {
        // your setup code here
    }

    window.asDynamic().draw = {
        // your draw code here
    }
}

这种方法可以最小化两个函数的定义和声明(看着你,C语言)。谢谢。

2

很遗憾,在Kotlin/JS中无法定义全局函数。但是可以使用普通模块类型,在其中使用在全局范围内定义的模块对象中的全局符号。

原始答案: "最初的回答"

// module M
fun foo() {}

which is accessible via M.foo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接