如何在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