如何在Kotlin for Javascript的类中设置一个静态属性

我有一种情况,我需要在Kotlin中定义一个类的静态属性,当它被编译成Javascript时,它就成为了这个类的一个真正的静态字段。 在这种情况下,伴侣对象不起作用。

例如,如果我有一个抽象类和它的实现类如下所示:

abstract class MyAbstractClass{ abstract val id: Int } class MyClass: MyAbstractClass(){ override val id: Int = 1 //I want this to actually be "static" on the MyClass } 

这个编译的Javascript是这样的:

 function MyAbstractClass() { } function MyClass() { MyAbstractClass.call(this); this.id_jz5fma$_0 = 1; } Object.defineProperty(MyClass.prototype, 'id', { get: function () { return this.id_jz5fma$_0; } }); 

但我需要它来编译是这样的:

 function MyAbstractClass() { } function MyClass() { MyAbstractClass.call(this); } MyClass.id = 1; 

这样, id字段实际上静态地存在于MyClass而不必创建一个MyClass的新实例。

我试过使用伴侣对象,但创建了一个名为MyClass$Companion的单独的对象/函数,然后将id字段赋值给该对象,永远不会实际将其静态分配给MyClass

我怎样才能在Kotlin中设置这样的静态字段呢?

现在我们没有直接的办法,所以我创建了一个问题https://youtrack.jetbrains.com/issue/KT-18891

作为一个解决方法,你可以写一个这样的函数:

 inline fun <reified T : Any> addStaticMembersTo(source: Any) { val c = T::class.js.asDynamic() val ownNames = js("Object").getOwnPropertyNames(source) as Array<String> val protoNames = js("Object").getOwnPropertyNames(source.asDynamic().constructor.prototype) as Array<String> for (name in ownNames + protoNames) { c[name] = source.asDynamic()[name] } } 

并使用像:

 class A { companion object { init { addStaticMembersTo<A>(object { val bar = 1 fun foo() {} }) } } } 

甚至可以将伴随对象的成员作为类的静态成员提供:

 class B { companion object { val bar = 1 fun foo() {} // should be at the end of companion object init { addStaticMembersTo<B>(this) } } } 

完整的例子可在这里: https : //try.kotl.in/#/UserProjects/uube1qikg3vsegtnefo0ad0jag/30f1qf87dt5k5vjhciirt4t108