Конструктор классов
Конструктор классов
Технический фундамент жизненного цикла экземпляра
При new SomeClass(...) происходит последовательность шагов:
- Создается пустой объект-экземпляр.
- Его прототип связывается с
SomeClass.prototype. - Вызывается
constructorс переданными аргументами. - Возвращается инициализированный экземпляр (если явно не возвращен другой объект).
Поэтому качество конструктора напрямую определяет корректность стартового состояния модели.
Смотри, что важно: если constructor явно возвращает объект, то результатом new станет этот объект (и он может не иметь методов класса). Возврат примитива (number/string/...) будет проигнорирован.
class A {
constructor() {
return { x: 1 };
}
}
const a = new A();
console.log(a.x); // 1
console.log(a instanceof A); // false
Анти-провал: почти всегда constructor должен только инициализировать this и не возвращать другой объект вручную.
Зачем нужен constructor
Когда ты создаешь экземпляр класса, ему почти всегда нужны начальные данные: имя пользователя, цена товара, статус задачи, настройки сессии. constructor это специальный метод, который запускается автоматически при new и отвечает за начальную инициализацию объекта.
Ключевой момент: constructor задает стартовое состояние экземпляра и фиксирует контракт входных данных.
Проверь себя: почему важно, чтобы экземпляр сразу после создания был в валидном состоянии?
Базовый синтаксис constructor
class User {
constructor(name, email) {
this.name = name;
this.email = email;
this.isActive = true;
}
}
const user = new User('Аня', 'anya@example.com');
console.log(user);
Что происходит:
new User(...)создает новый объект;constructorполучает аргументы;thisуказывает на новый экземпляр;- свойства записываются в объект.
Здесь часто путаются: constructor не нужно вызывать вручную, он срабатывает автоматически.
Значения по умолчанию
Если часть данных опциональна, удобно задавать дефолты прямо в параметрах.
class Task {
constructor(title, priority = 'normal') {
this.title = title;
this.priority = priority;
this.done = false;
}
}
console.log(new Task('Проверить PR'));
Смотри, что важно: дефолты уменьшают количество ошибок из-за undefined и делают API класса удобнее.
Валидация в конструкторе
Если входные данные критичны, их нужно проверять в момент создания.
class Product {
constructor(name, price) {
if (typeof name !== 'string' || name.trim() === '') {
throw new Error('Некорректное имя товара');
}
if (typeof price !== 'number' || price < 0) {
throw new Error('Некорректная цена');
}
this.name = name;
this.price = price;
}
}
Анти-провал: лучше не создать объект вообще, чем создать объект в плохом состоянии и ловить баги позже.
Проверь себя: почему стратегия fail fast особенно полезна внутри constructor?
Реальные микро-сценарии
- Модель пользователя при регистрации.
Конструктор нормализует и проверяет вход: имя, email, флаги статуса.
- Модель корзины.
Конструктор задает начальные поля (items, currency, createdAt) и гарантирует, что объект готов к работе сразу.
- UI-компонент.
Конструктор принимает конфиг и подготавливает состояние для рендера.
Частые ошибки новичков
- Писать тяжелую бизнес-логику внутри
constructor. - Забывать задавать важные поля и получать "полупустой" объект.
- Не валидировать критичные входы.
- Пытаться иметь несколько
constructorв одном классе (в JS это нельзя).
class Example {
constructor(a) {}
// constructor(b) {} // SyntaxError: только один constructor
}
Дополнительный пример: конструктор с объектом параметров и дефолтами.
class Session {
constructor({ userId, locale = 'ru', isGuest = false } = {}) {
if (!userId && !isGuest) throw new Error('userId required for non-guest');
this.userId = userId ?? null;
this.locale = locale;
this.isGuest = isGuest;
}
}
Лучше держать constructor компактным: инициализация + базовая валидация.
Что будет, если изменить входные данные
В new Product('Книга', 500) объект создастся нормально. В new Product('', 500) сработает ошибка валидации имени. В new Product('Книга', -1) сработает ошибка по цене. Такое поведение предсказуемо и защищает от скрытых багов.
Проверь себя: что лучше для поддерживаемости - создать объект с price = -1 и чинить позже или бросить ошибку сразу?
Краткий итог
constructorавтоматически запускается при создании экземпляра черезnew.- Его задача - корректно инициализировать стартовое состояние объекта.
- Значения по умолчанию делают API класса удобнее и надежнее.
- Валидация в
constructorзащищает систему от невалидных экземпляров. - Хороший
constructorкороткий, предсказуемый и без лишней бизнес-магии.