运行 一个 'constructor' 或函数,在 class 字段初始化之后,以一种理智的方式?
Run a 'constructor' or function, after class fields initialized, in a sane way?
我想使用 ES6 public class 字段:
class Superclass {
constructor() {
// would like to write modular code that applies to all
// subclasses here, or similarly somewhere in Superclass
this.example++; // does NOT WORK (not intialized)
//e.g. doStuffWith(this.fieldTemplates)
}
}
class Subclass extends Superclass {
example = 0
static fieldTemplates = [
Foo,
function() {this.example++},
etc
]
}
问题:
ES6 public 字段未在构造函数之前初始化,仅在 current 构造函数之前初始化。例如,当调用super()
时,任何子字段都还没有定义,就像this.example
还不存在。静态字段将已经被定义。因此,例如,如果从 superclass 构造函数中调用适当的 .bind
来执行代码 function(){this.example++}
,它将失败。
解决方法:
一种解决方法是在所有 ES6 public classes 已正确初始化之后放置所有初始化逻辑。例如:
class Subclass extends Superclass {
example = 0
lateConstructor = (function(){
this.example++; // works fine
}).bind(this)()
}
有什么解决办法?
然而,这将涉及重写每个 class。我想要这样的东西,只需在 Superclass.constructor 中定义它,像 Object.defineProperty(this, 'lateConstructor', {some magic})
这样神奇的东西(据称 Object.defineProperty
在内部是 es6 static 字段的方式定义,但我看不到这样的解释如何在 mozilla 文档中以编程方式实现这一点;在使用 Object.getOwnPropertyDescriptor
检查我上面的 immediately-.binded-and-evaluated cludge 之后,我倾向于相信没有办法将 属性 描述符定义为 thunk;该定义可能在从 super()
返回后执行,可能会立即评估并分配给 class,如 let exampleValue = eval(...); Object.defineProperty(..{value:exampleValue})
)。或者我可以做一些可怕的事情,比如在 Superclass.constructor 中做 setTimeout(this.lateConstructor,0)
但这会破坏很多东西并且不能很好地组合。
我也许可以尝试只在各处使用对象的层次结构,但是有没有什么方法可以为父 class 中的所有子 class 实现一些全局逻辑?除了让吸气剂让一切变得懒惰之外?感谢您的任何见解。
参考文献:
Run additional action after constructor --(问题:这需要包装所有子classes)
Can I create a thunk to run after the constructor?
不,那不可能。
How to run code after class fields are initialized, in a sane way?
将代码放入定义这些字段的 class 的构造函数中。
Is there some way to implement some global logic for all subclasses in the parent class?
是:定义一个方法。 subclass 可以从其构造函数中调用它。
刚想到一个解决方法(可以分层组合)。以一种不太令人满意的方式回答我自己的问题(人们可以随意 post 更好的解决方案):
// The following illustrates a way to ensure all public class fields have been defined and initialized
// prior to running 'constructor' code. This is achieved by never calling new directly, but instead just
// running Someclass.make(...). All constructor code is instead written in an init(...) function.
class Superclass {
init(opts) { // 'constructor'
this.toRun(); // custom constructor logic example
}
static make() { // the magic that makes everything work
var R = new this();
R.init(...arguments);
return R;
}
}
class Subclass extends Superclass {
subclassValue = 0 // custom public class field example
init(toAdd, opts) { // 'constructor'
// custom constructor logic example
this.subclassValue += toAdd; // may use THIS before super.init
super.init(opts);
// may do stuff afterwards
}
toRun() { // custom public class method example
console.log('.subclassValue = ', this.subclassValue);
}
}
演示:
> var obj = Subclass.make(1, {});
.subclassValue = 1
> console.log(obj);
Subclass {
subclassValue: 1
__proto__: Superclass
}
我想使用 ES6 public class 字段:
class Superclass {
constructor() {
// would like to write modular code that applies to all
// subclasses here, or similarly somewhere in Superclass
this.example++; // does NOT WORK (not intialized)
//e.g. doStuffWith(this.fieldTemplates)
}
}
class Subclass extends Superclass {
example = 0
static fieldTemplates = [
Foo,
function() {this.example++},
etc
]
}
问题:
ES6 public 字段未在构造函数之前初始化,仅在 current 构造函数之前初始化。例如,当调用super()
时,任何子字段都还没有定义,就像this.example
还不存在。静态字段将已经被定义。因此,例如,如果从 superclass 构造函数中调用适当的 .bind
来执行代码 function(){this.example++}
,它将失败。
解决方法:
一种解决方法是在所有 ES6 public classes 已正确初始化之后放置所有初始化逻辑。例如:
class Subclass extends Superclass {
example = 0
lateConstructor = (function(){
this.example++; // works fine
}).bind(this)()
}
有什么解决办法?
然而,这将涉及重写每个 class。我想要这样的东西,只需在 Superclass.constructor 中定义它,像 Object.defineProperty(this, 'lateConstructor', {some magic})
这样神奇的东西(据称 Object.defineProperty
在内部是 es6 static 字段的方式定义,但我看不到这样的解释如何在 mozilla 文档中以编程方式实现这一点;在使用 Object.getOwnPropertyDescriptor
检查我上面的 immediately-.binded-and-evaluated cludge 之后,我倾向于相信没有办法将 属性 描述符定义为 thunk;该定义可能在从 super()
返回后执行,可能会立即评估并分配给 class,如 let exampleValue = eval(...); Object.defineProperty(..{value:exampleValue})
)。或者我可以做一些可怕的事情,比如在 Superclass.constructor 中做 setTimeout(this.lateConstructor,0)
但这会破坏很多东西并且不能很好地组合。
我也许可以尝试只在各处使用对象的层次结构,但是有没有什么方法可以为父 class 中的所有子 class 实现一些全局逻辑?除了让吸气剂让一切变得懒惰之外?感谢您的任何见解。
参考文献:
Run additional action after constructor --(问题:这需要包装所有子classes)
Can I create a thunk to run after the constructor?
不,那不可能。
How to run code after class fields are initialized, in a sane way?
将代码放入定义这些字段的 class 的构造函数中。
Is there some way to implement some global logic for all subclasses in the parent class?
是:定义一个方法。 subclass 可以从其构造函数中调用它。
刚想到一个解决方法(可以分层组合)。以一种不太令人满意的方式回答我自己的问题(人们可以随意 post 更好的解决方案):
// The following illustrates a way to ensure all public class fields have been defined and initialized
// prior to running 'constructor' code. This is achieved by never calling new directly, but instead just
// running Someclass.make(...). All constructor code is instead written in an init(...) function.
class Superclass {
init(opts) { // 'constructor'
this.toRun(); // custom constructor logic example
}
static make() { // the magic that makes everything work
var R = new this();
R.init(...arguments);
return R;
}
}
class Subclass extends Superclass {
subclassValue = 0 // custom public class field example
init(toAdd, opts) { // 'constructor'
// custom constructor logic example
this.subclassValue += toAdd; // may use THIS before super.init
super.init(opts);
// may do stuff afterwards
}
toRun() { // custom public class method example
console.log('.subclassValue = ', this.subclassValue);
}
}
演示:
> var obj = Subclass.make(1, {});
.subclassValue = 1
> console.log(obj);
Subclass {
subclassValue: 1
__proto__: Superclass
}