【问题标题】:Parent constructor call overridden functions before all child constructors are finished在所有子构造函数完成之前,父构造函数调用重写的函数
【发布时间】: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


【解决方案1】:

以下代码可以满足您的需求,但目前仅支持 FF 41+ 和 Chrome 47+(请参阅https://kangax.github.io/compat-table/es6/

class Bot{
    constructor(){
        if (new.target === Bot)
            this.render();
    }
    render(){
        console.log('Bot rendered');
    }
}

class DevilBot extends Bot{
    constructor(){
        super();
        this.color = 0xB4D333;
        this.render();
    }
    render(){
        console.log('DevilBot rendered with', this.color);
    }
}

var bot = new Bot();       // Bot rendered
var dev = new DevilBot();  // DevilBot rendered with 11850547

【讨论】:

    猜你喜欢
    • 2011-03-06
    • 2018-01-31
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多