Коротка відповідь
juniorES5 функція‑конструктор — це просто функція, що створює об’єкт через оператор new; властивості додаються в конструкторі, а методи – у прототипі. ES2015 клас — синтаксичний сахар над тією ж механікою: конструктор, прототип і static‑методи оголошуються в одному блоку. Ключова різниця – клас обмежує доступ до конструктора (new лише після оголошення) і автоматично встановлює прототип, а також підтримує super‑виклик та private поля через # синтаксис.
Повне пояснення
Що це і навіщо
- Функція‑конструктор (ES5) – традиційний спосіб створення об’єктів у JavaScript.
- Клас (ES2015) – новий синтаксис, що полегшує читання і підтримку коду.
Ключові принципи/терміни
new– створює новий об’єкт, встановлює його прототип.prototype– об’єкт, що містить спільні методи.constructor– функція, яка виконується при створенні об’єкта.super()– виклик конструктора батьківського класу.#privateField– приватне поле, доступне лише в межах класу.
Як це працює
- При виклику
new Constructor()створюється порожній об’єкт. - Встановлюється його
[[Prototype]]наConstructor.prototype(абоClassName.prototype). - Виконується тіло конструктора, що може додавати властивості.
- Після завершення конструктор повертає об’єкт (якщо явно не повернуто інший).
Практика і реалізація
// ES5
function Person(name){ this.name = name; }
Person.prototype.sayHi = function(){ console.log('Hi, ' + this.name); };
const p1 = new Person('Alice');
p1.sayHi();
// ES2015
class Person {
constructor(name){ this.name = name; }
sayHi(){ console.log('Hi, ' + this.name); }
}
const p2 = new Person('Bob');
p2.sayHi();
Тестування (Jest)
test('class method works', () => {
const p = new Person('Eve');
expect(p.sayHi()).toBeUndefined(); // console.log returns undefined
});
Особливості в контексті JS Core
- Клас автоматично створює
[[Prototype]]і встановлює його вClassName.prototype. - Методи класу визначаються як non‑enumerable і configurable, що відповідає поведінці прототипу ES5.
- Клас підтримує
staticметоди, які доступні лише через конструктор. - Підтримка
super()дозволяє викликати батьківський конструктор без ручного доступу доParent.call(this, …).
Оптимізація та edge cases
- У ES5 можна випадково змінити
prototypeпісля створення об’єктів, що призведе до різних поведінок. У класах це заборонено. - Клас не дозволяє викликати конструктор без
new; це запобігає помилкам типу "this is undefined". - Private поля (
#field) в класах гарантують реальну приватність, у прототипі це не можливо.
Часті помилки
- Виклик конструктора без
newу ES5 →thisпосилається на глобальний об’єкт. - Зміна
Person.prototypeпісля створення екземплярів → нові методи не доступні старим. - Використання
thisу функціях‑методах без прив’язки → контекст втрачається. - Неправильне використання
super()у класі‑потомку → помилка "super() called before calling super constructor". - Забудьте про
returnу конструкторі ES5 → повертається новий об’єкт автоматично. - Визначення
staticу ES5 черезPerson.staticMethod = …→ не є частиною прототипу. - Підключення
#privateFieldу старих браузерах → не підтримується. - Використання
newз функцією, що повертає об’єкт → конструктор ігнорується.
Cheatsheet
new Func()→ створює об’єкт, встановлює прототип.Func.prototype– спільні методи.class C{}→ синтаксичний сахар над функцією‑конструктором.static– доступно через конструктор, а не екземпляр.#privateField– реальна приватність.
Follow‑up питання
- Як працює
super()у класах? - Чому методи класу є non‑enumerable?
- Які переваги приватних полів у класах порівняно з ES5?