Коротка відповідь
middlePrototype — це патерн, що дозволяє створювати нові об’єкти шляхом копіювання існуючого, замість використання конструкторів. У JavaScript це просто `Object.create(proto)` або розширений `clone()` з глибоким копіюванням. Такий підхід економить час, коли потрібна точна копія складної структури, а не новий екземпляр класу.
Повне пояснення
1. Що це і навіщо
Prototype — патерн створення, що дозволяє копіювати існуючий об’єкт (прототип) замість створення нового через конструктор. Він у GoF розташований в секції "Creational" і корисний, коли створення об’єкта дорого або складно.
2. Принцип роботи / алгоритм
Патерн базується на ролі "Prototype" (об’єкт, що копіюється) і «Client» (той, хто викликає clone). Клієнт отримує копію через метод clone(), який повертає новий об’єкт з тією ж прототипною ланцюжком. Якщо потрібне глибоке копіювання, clone рекурсивно копіює властивості.
3. Реалізація (JS / TS)
- Базова реалізація:
class Prototype {
constructor(public data: any) {}
clone() { return new Prototype(this.data); }
}
- Реалістичний приклад (копіювання конфігурації сервера):
const baseConfig = {
host: 'localhost',
port: 3000,
middleware: [] as string[]
};
function cloneConfig(cfg: typeof baseConfig) {
return JSON.parse(JSON.stringify(cfg));
}
const prod = cloneConfig(baseConfig);
prod.host = 'api.prod.com';
- Спрощений для новачка (копія DOM елемента):
const original = document.getElementById('card');
const copy = original?.cloneNode(true) as HTMLElement;
document.body.appendChild(copy);
4. Тестування (Jest або Vitest)
test('clone creates a new instance with same data', () => {
const proto = new Prototype({a:1});
const copy = proto.clone();
expect(copy).not.toBe(proto);
expect(copy.data).toEqual({a:1});
});
5. Проблеми та edge cases
- Поверхневе копіювання:
clone()може не дублювати вкладені об’єкти, що веде до спільного стану. - Сторонні залежності: копія може містити посилання на зовнішні ресурси, що не слід дублювати.
- Cyclical dependencies: рекурсивне копіювання циклічних структур викликає стек‑overflow.
- Перевантаження конструкторів: використання
newзамістьObject.createможе створювати зайві об’єкти. - Проблеми продуктивності: глибоке копіювання великих об’єктів витрачає пам’ять і час.
6. Оптимізація та продуктивність
- Використання
Object.create(proto)мінімізує створення нових об’єктів. - Для глибокого копіювання можна застосовувати
structuredClone(ES2021) або бібліотеки типу lodash. - У випадку великих даних варто розглянути патерн «Flyweight» для спільного використання.
7. Без JS / архітектурні альтернативи
- У чистій HTML/CSS можна копіювати шаблони через
<template>іdocument.importNode. - У серверних мовах без патерна можна просто викликати конструктор з копією параметрів.
8. Cheatsheet + follow-up
- Cheatsheet:
clone()→ shallow copy;structuredClone()→ deep copy. - Interview Q1: Як уникнути циклічних залежностей при копіюванні?
- Interview Q2: Коли варто використовувати Prototype замість Factory Method?