如何在Kotlin for Javascript中的类中设置静态属性
问题描述:
我有一种情况,我需要在Kotlin的类中定义一个静态属性,并且当它编译为Javascript时,它已成为该类上的一个真正的静态字段。在这种情况下,伴侣对象不起作用。如何在Kotlin for 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
如果您编译到JVM有一个'@ JvmStatic'注解。也许这有一个相当于JS的? – Mibac
相关问题:https://youtrack.jetbrains.com/issue/KT-18891 – bashor
您可以在类上声明静态变量,但不能声明抽象静态变量。哪有这回事。 – Joshua