Кратко
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() создаёт базовую часть объекта).
Примеры
**Самый простой:**
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); // 5extends + super() — наследование с добавлением собственных свойств.
**Простой:**
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() — вызов родительского метода.
**Реальный пример:**
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) — приватные и защищённые поля.