如何在 Kotlin 的 class 上为 Javascript 设置静态 属性
How to set a static property on a class in Kotlin for Javascript
我有一种情况,我需要在 Kotlin 中的 class 上定义静态 属性,当它编译为 Javascript 时,它会成为 属性 上的真正静态字段 class。在这种情况下,伴随对象不起作用。
例如,如果我有一个抽象 class 及其实现 class,如下所示:
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
的单独 object/function,然后将 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 的静态成员使用:
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
我有一种情况,我需要在 Kotlin 中的 class 上定义静态 属性,当它编译为 Javascript 时,它会成为 属性 上的真正静态字段 class。在这种情况下,伴随对象不起作用。
例如,如果我有一个抽象 class 及其实现 class,如下所示:
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
的单独 object/function,然后将 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 的静态成员使用:
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