【发布时间】:2015-12-03 16:06:36
【问题描述】:
ECMAScript 6 (Harmony) 引入了classes,能够从另一个继承。假设我有一个游戏和一些基本类来描述机器人行为的基本内容。我简化了我的真实架构,但假设我需要运行render 和其他一些例程,我将这个调用放在基本的Bot 类中。
class Bot{
constructor(){
render();
}
render(){}
}
然后每个机器人覆盖它的render 函数并且可以在构造函数中进行一些设置:
class DevilBot extends Bot{
constructor(){
super();
this.color = 0xB4D333;
}
render(){
createSomeMesh(this.color);
}
}
这里的问题是,在我调用 super() 之前 - this 不存在。但是super(父构造函数)将调用需要在子构造函数中定义的color 变量的覆盖render。我可以在父构造函数中假设子对象将实现一些具有所有需要设置的init 函数并调用它:
class Bot{
constructor(){
if (this.init) this.init();
render();
}
render(){}
}
class DevilBot extends Bot{
init(){
this.color = 0xB4D333;
}
render(){
createSomeMesh(this.color);
}
}
但是这种方法有多好?解决此类问题的首选方法是什么?
【问题讨论】:
-
唯一的解决方案是不要在构造函数中调用可覆盖的方法。在 C# 中执行它会给你一个warning。
-
这就是为什么某些类型的对象通常有一个构造函数和一个单独的
.init()方法的原因之一,因为.init()方法在对象完全形成并且所有覆盖都到位之后运行。跨度> -
解决方案可以简单到不自动调用依赖于实例属性的其他函数(例如
render)。在调用Bot子类后手动调用this.render()有什么害处? PS,要在你的类中调用成员函数,你需要this.render()而不是render()。 -
这看起来像是糟糕的设计。构造函数的目的是构造和初始化对象,而不是
render它们(副作用) -
@Bergi,这看起来像是糟糕的设计,只是因为我在此示例中使用
render进行简化。正如我在之前的评论中所写,在实际架构中,我有更复杂的代码要隐藏在父对象中。
标签: javascript ecmascript-6 javascript-objects