JS Intermediate

Наследование классов

Научиться создавать дочерние классы через extends, вызывать родительский constructor через super, и переопределять методы.

Средний (Intermediate)
Нужно знать:Классы

Кратко

extends создаёт дочерний класс, наследующий методы родителя. super() вызывает родительский constructor. До вызова super() нельзя использовать this — потому что дочерний объект ещё не создан.


Подробно

Наследование:

class Animal { constructor(name) { this.name = name; } speak() { return ${this.name} издаёт звук; } }

class Dog extends Animal { speak() { return ${this.name} гавкает; } }

const rex = new Dog('Рекс'); console.log(rex.speak()); // 'Рекс гавкает'

super() — вызов родительского constructor:

class Dog extends Animal { constructor(name, breed) { super(name); // ОБЯЗАТЕЛЬНО до this! this.breed = breed; } }

Почему super() перед this? Дочерний класс не может использовать this до вызова super(), потому что родительский constructor ещё не инициализировал объект.

Переопределение методов: Дочерний класс может переопределить метод родителя. Если нужен доступ к родительскому методу: super.method().


Ментальная модель

Наследование — как ребёнок наследует черты родителя, но может их изменить. Ребёнок не может существовать без родителя (super() создаёт базовую часть объекта).


Примеры

**Самый простой:**

javascript
class Shape {
  constructor(color) {
    this.color = color;
  }
}

class Circle extends Shape {
  constructor(color, radius) {
    super(color);
    this.radius = radius;
  }
}

const red = new Circle('красный', 5);
console.log(red.color);  // 'красный'
console.log(red.radius); // 5

extends + super() — наследование с добавлением собственных свойств.

**Простой:**

javascript
class User {
  constructor(name) {
    this.name = name;
  }
  greet() {
    return `Привет, ${this.name}`;
  }
}

class Admin extends User {
  greet() {
    return `${super.greet()} (Admin)`;
  }
}

const admin = new Admin('Анна');
console.log(admin.greet()); // 'Привет, Анна (Admin)'

super.greet() — вызов родительского метода.

**Реальный пример:**

javascript
class EventEmitter {
  #listeners = {};

  on(event, callback) {
    if (!this.#listeners[event]) {
      this.#listeners[event] = [];
    }
    this.#listeners[event].push(callback);
  }

  emit(event, ...args) {
    const callbacks = this.#listeners[event] || [];
    callbacks.forEach(cb => cb(...args));
  }
}

class Logger extends EventEmitter {
  log(message) {
    console.log(`[LOG] ${message}`);
    this.emit('log', message);
  }
}

const logger = new Logger();
logger.on('log', msg => console.log(`Сохранено: ${msg}`));
logger.log('Запуск'); // [LOG] Запуск + Сохранено: Запуск

Наследование: Logger получает on/emit от EventEmitter.


Частые ошибки

**Неправильно:** Использовать this до super()

**Почему:** Дочерний класс не может использовать this до вызова super().

**Правильно:** Сначала super(), потом this.

**Неправильно:** Забывать super() в constructor

**Почему:** Без super() — ReferenceError при использовании this.

**Правильно:** Если у дочернего класса есть constructor — вызовите super().

**Неправильно:** Думать, что extends — это копирование

**Почему:** extends создаёт НАСЛЕДОВАНИЕ (цепочку прототипов), а не копирование методов.

**Правильно:** extends — цепочка прототипов: Dog → Animal → Object.


Важно запомнить

  • extends создаёт дочерний класс
  • super() — вызов родительского constructor
  • super() ОБЯЗАТЕЛЕН до this в дочернем constructor
  • super.method() — вызов родительского метода
  • Переопределение методов — нормальная практика

Связь

Назад: Вы знаете классы (JI8) — теперь вы знаете, как классы соотносятся друг с другом.

Вперёд: Следующий урок (JI10) — приватные и защищённые поля.

Материалы курса JS Intermediate — PROlab Academy.