Фабричные функции или классы в JavaScript и TypeScript: когда что выбрать?
Порождающие паттерны
Класс даёт общие методы в прототипе, `instanceof`, наследование и декораторы; фабричная функция — приватность через замыкание, отсутствие `this` и `new` и свободу вернуть любой объект.
Фабричная функция
- Возвращает объект-литерал, приватное состояние живёт в замыкании и недоступно снаружи.
- Нет потерянного
this: метод можно передать колбэком (onClick={counter.inc}). - Может вернуть кэшированный экземпляр, подтип или Proxy — вызывающий не заметит.
- Минус: у каждого объекта свои копии методов — на сотнях тысяч экземпляров это ощутимая память;
instanceofне работает.
Класс
- Методы лежат в прототипе — одна копия на все экземпляры.
#private-поля (ES2022) приватны в рантайме, аprivateв TS — только при компиляции.- Нужен для DI на декораторах (NestJS, Angular), для
instanceof, для наследования отErrorилиHTMLElement.
function createCounter(start = 0) {
let count = start;
return {
inc: () => ++count,
get value() { return count; },
};
}
const counter = createCounter();
const inc = counter.inc; // this не нужен
inc();
console.log(counter.value); // 1Как выбирать
- Много экземпляров, иерархия ошибок, фреймворк на декораторах → класс.
- Модульный сервис, композиция поведения, клиент API с конфигом → фабрика.
Коротко для собеседования
Фабрика даёт настоящую приватность замыканием и методы, которые не теряют this, но копирует методы в каждый объект. Класс экономит память через прототип и нужен для instanceof, наследования и декораторов; их легко совместить, спрятав new за фабрикой.