Когда мне нужно вызывать `super` из конструктора?

Читая Dr. Блог Акселя Раушмайера о классах ES6, я понимаю, что производный класс имеет следующий конструктор по умолчанию, если он не указан

constructor(...args) {
    super(...args);
}

Я также понимаю, что если я хочу использовать this в конструкторе, мне сначала нужно вызвать super, иначе this еще не будет инициализирован (выдает ReferenceError).

constructor(width, height) {
    this.width = width;  // ReferenceError
    super(width, height);
    this.height = height; // no error thrown
    ...
}

Верно ли тогда следующее предположение? (а если нет, не могли бы вы объяснить условия, при которых я должен явно вызывать super)

Для производных классов мне нужно только явно вызвать super, когда...

  1. Мне нужно получить доступ к this из конструктора
  2. Конструктор суперкласса требует других аргументов, чем конструктор производного класса.

Есть ли другие случаи, когда я должен включать вызов конструктора суперкласса?


person sfletche    schedule 27.12.2016    source источник
comment
Нет, здесь нету. Какие доказательства вы хотите для этого утверждения?   -  person Felix Kling    schedule 27.12.2016
comment
когда вы создаете такой класс, как class ABC extends DEF { ..., вам нужно поставить super(...args);, потому что вы только что указали с помощью extends DEF, что хотите получить от него. Если вы не наследуете какой-либо класс, просто не ставьте «супер» в конструкторе ABC. Это так просто.   -  person Azamantes    schedule 27.12.2016
comment
@Azamantes: нет необходимости вызывать super, если родительский класс принимает те же аргументы, что и дочерний класс.   -  person Felix Kling    schedule 27.12.2016
comment
что, если производный класс определяет конструктор? мне тогда нужно включить явный вызов супер? другими словами, включен ли вызов super по умолчанию только как часть конструктора по умолчанию? (не уверен в случае использования здесь, просто пытаюсь думать о крайних случаях)   -  person sfletche    schedule 27.12.2016
comment
@sfletche Да, для всех конструкторов нет вызова super по умолчанию, это только часть конструктора по умолчанию.   -  person Bergi    schedule 27.12.2016


Ответы (2)


Да, это звучит правильно, хотя и несколько странно сформулировано. Правила должны быть

  • В производном классе вам всегда1 нужно вызывать конструктор super(…)
  • Если вы не делаете больше, чем конструктор по умолчанию, вы можете опустить весь constructor(){}, что, в свою очередь, приведет к тому, что код вашего класса не будет содержать супервызов.

1: вам не нужно вызывать его в подозрительном пограничном случае явного returning объекта, что вы вряд ли когда-нибудь сделаете.

person Bergi    schedule 27.12.2016

Вам нужно вызвать super в конструкторе подкласса в этих случаях:

  • Вы хотите сослаться на this в конструкторе подкласса
  • Вы не возвращаете другой объект в конструкторе подкласса

В других случаях вы можете вызвать его, если хотите, чтобы конструктор суперкласса работал, но это не обязательно.

class SuperClass{
  constructor() {
    console.log('SuperClass');
  }
}
class SubClass1 extends SuperClass {
  constructor() {
    console.log('SubClass1');
    super();
    return {};
  }
}
class SubClass2 extends SuperClass {
  constructor() {
    console.log('SubClass2');
    return {};
  }
}
new SubClass1();
new SubClass2();

Я не понимаю, какое значение имеет порядок аргументов при принятии решения о том, следует ли вызывать super или нет.

person Oriol    schedule 27.12.2016
comment
когда я хочу сослаться на this в любом месте подкласса? или просто где-нибудь в конструкторе подкласса? - person sfletche; 27.12.2016
comment
@sfletche да, он имеет в виду конструктор - person Bergi; 27.12.2016
comment
@sfletche Остальные вещи в классе - это просто методы, я имел в виду конструктор, да. - person Oriol; 27.12.2016