Skip to main content

Чи можна не оголошувати constructor

Так, конструктор у класі можна не оголошувати: JavaScript автоматично створює його за замовчуванням. Форма цього неявного конструктора залежить від того, чи успадковує клас інший клас через extends.

Теорія

TL;DR

  • Якщо constructor() не написано, рушій додає його сам.
  • Клас без extends отримує порожній конструктор, який нічого не робить.
  • Клас з extends отримує constructor(...args) { super(...args); }, тобто прозоро передає аргументи батькові.
  • Власний конструктор потрібен, коли є нові поля або логіка ініціалізації.
  • У похідному класі власний конструктор зобов'язаний викликати super() до першого використання this.

Швидкий приклад

javascript
class User { greet() { console.log("Hi!"); } } const u = new User(); u.greet(); // Hi!

Під капотом рушій створює приблизно такий конструктор:

javascript
class User { constructor(...args) { super(...args); // тільки якщо є батьківський клас } }

Клас без успадкування

Якщо клас не має extends, стандартний «порожній» конструктор просто нічого не робить.

javascript
class User {} // рівнозначно: class User { constructor() {} }

Обидва записи дають той самий результат: new User() створює порожній об'єкт із прототипом User.prototype. Методи класу при цьому працюють як звичайно, бо вони лежать у прототипі, а не створюються в конструкторі.

Клас, що успадковує інший

Якщо клас успадковує інший через extends, конструктор обов'язковий лише тоді, коли ви хочете додати власну логіку та використати this. Якщо його немає, рушій сам додає конструктор, який викликає super().

javascript
class Animal { constructor(name) { this.name = name; } } class Dog extends Animal {} // Еквівалентно: class Dog extends Animal { constructor(...args) { super(...args); } } const dog = new Dog("Rex"); console.log(dog.name); // Rex

Саме тому new Dog("Rex") коректно заповнює name, хоча в Dog не написано жодного рядка конструктора.

Якщо ви пишете конструктор у нащадку

Тоді ви зобов'язані викликати super() перед використанням this, інакше буде помилка.

javascript
class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor(name, breed) { // super() обов'язково першим super(name); this.breed = breed; } }

Якщо не викликати:

javascript
constructor(name, breed) { this.breed = breed; // ReferenceError: Must call super constructor before accessing 'this' }

Причина в тому, що в похідному класі об'єкт this створює саме конструктор батька, тож до виклику super() посилатися просто нема на що.

Коли конструктор потрібен

СитуаціяЧи потрібен constructor()
Клас без успадкуванняНе потрібен
Клас успадковує інший, але не додає нової поведінкиНе потрібен
Клас успадковує і додає власні поляПотрібен, і треба викликати super()
Треба виконати логіку під час створення екземпляра (ініціалізація, перевірка)Потрібен

Типові помилки

  • Писати порожній constructor() {} «про всяк випадок»: це рівно те, що рушій зробить і без вас, тільки зайвий шум у коді.
  • Писати в нащадку constructor(name) { super(); } і губити аргументи, замість super(name) або super(...args).
  • Звертатися до this або до полів класу до super(): буде ReferenceError, а не undefined.
  • Думати, що без конструктора методи класу перестануть працювати. Методи живуть у прототипі й від конструктора не залежать.
  • Оголошувати конструктор у нащадку лише для того, щоб викликати super(...args): конструктор за замовчуванням робить це сам.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.