Родительский конструктор вызывает переопределенные функции до завершения всех дочерних конструкторов

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 (родительский конструктор) вызовет переопределенный render, для которого потребуется переменная color, определенная в дочернем конструкторе. Я могу предположить, что в родительском конструкторе дочерний объект реализует некоторую функцию init со всеми необходимыми настройками и вызывает ее:

class Bot{
 constructor(){
 if (this.init) this.init();
 render();
 }
 render(){}
}
class DevilBot extends Bot{
 init(){
 this.color = 0xB4D333;
 }
 render(){
 createSomeMesh(this.color);
 }
}

Но насколько хорош этот подход и что является предпочтительным способом решения такой проблемы?

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

licensed under cc by-sa 3.0 with attribution.