Skip to main content

Що робить return всередині конструктора?

1. Звичайна поведінка конструктора

Коли ти створюєш екземпляр класу:

javascript
class User { constructor(name) { this.name = name; } } const u = new User("Alice");

JS під капотом робить приблизно таке:

  1. Створює новий порожній об'єкт {}.
  2. Встановлює прототип цього об'єкта → User.prototype.
  3. Викликає constructor із this, що посилається на цей новий об'єкт.
  4. Повертає this із конструктора (за умовчанням).

Тобто якщо ти нічого не повертаєш, return this виконується неявно.


2. Що якщо явно використати return?

Якщо return повертає об'єкт, він замінює this

javascript
class User { constructor(name) { this.name = name; return { custom: "a different object" }; } } const u = new User("Alice"); console.log(u); // { custom: "a different object" }

Тобто якщо ти повертаєш об'єкт, він замінює екземпляр, що створюється.


Якщо return повертає примітив (число, рядок, булеве значення тощо)

Примітиви ігноруються, і повертається початковий this.

javascript
class User { constructor(name) { this.name = name; return 42; } } const u = new User("Alice"); console.log(u); // User { name: "Alice" }

Важливо: конструктор не може «перезаписати» this примітивом.


3. Чому так зроблено

JS дозволяє повертати об'єкт із конструктора, щоб ти міг підмінити екземпляр, якщо потрібно повернути щось особливе.

Приклад: реалізуємо синглтон (один об'єкт для всіх викликів):

javascript
class Database { constructor() { if (Database.instance) { return Database.instance; // завжди повертає один об'єкт } this.connected = true; Database.instance = this; } } const a = new Database(); const b = new Database(); console.log(a === b); // true

Тут return this не потрібен, бо JS робить це сам, але return Database.instance підміняє екземпляр, що створюється.


4. Чи можна використовувати return у класах без extends?

Так, можна, поведінка однакова. Але якщо клас успадковується (extends) і ти повертаєш об'єкт, він теж замінить this:

javascript
class A {} class B extends A { constructor() { super(); return { name: "replacement" }; } } const b = new B(); console.log(b); // { name: "replacement" }

5. Що буде, якщо не викликати super() у нащадку і спробувати return?

javascript
class A {} class B extends A { constructor() { // Помилка, навіть якщо є return return { test: 1 }; } } new B(); // ReferenceError: Must call super constructor before returning from derived constructor

У класах-нащадках super() обов'язковий, навіть якщо ти повертаєш свій об'єкт.


6. Правила в одному місці

СценарійЩо повертається
Немає returnthis (створений екземпляр)
return thisтой самий екземпляр
return { ... }замість this підставляється цей об'єкт
return 42 / "hi" / trueігнорується, повертається this
Нащадок без super()Помилка (треба викликати super() до return)

Приклад для розуміння

javascript
class Example { constructor(x) { this.x = x; if (x > 10) return { value: "too large" }; } } console.log(new Example(5)); // Example { x: 5 } console.log(new Example(20)); // { value: "too large" }

Якщо x > 10, повертається "свій" об'єкт, якщо ні, звичайний екземпляр класу.


Підсумок

  • return у конструкторі не обов'язковий, за умовчанням повертається this.
  • Якщо повернути об'єкт, він замінить this.
  • Якщо повернути примітив, він ігнорується.
  • У класах, що успадковуються, super() обов'язковий до return.
  • Ця поведінка зручна для таких шаблонів, як Singleton, Factory, Proxy тощо.

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

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

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