Як зробити глибоку копію об'єкта?
Що таке "глибока копія"
Глибока копія (deep copy) - це коли створюється повністю незалежний об'єкт, включно з усіма вкладеними об'єктами й масивами. Зміни в копії не впливають на оригінал.
1. Сучасний спосіб - structuredClone()
Найнадійніший і найпростіший метод (доступний у всіх сучасних браузерах і Node.js ≥17).
const user = {
name: 'Alice',
address: { city: 'Kyiv', zip: 12345 },
tags: ['dev', 'frontend']
};
const clone = structuredClone(user);
clone.address.city = 'Lviv';
clone.tags.push('react');
console.log(user.address.city); // "Kyiv"
console.log(user.tags); // ['dev', 'frontend']Переваги:
- Копіює об'єкти, масиви, дати, Map, Set та ін.
- Безпечний і швидкий.
Обмеження:
- Не копіює функції та прототипи (вони втрачаються).
- Не підтримує
undefinedяк ключ (але підтримує як значення).
2. Через JSON.parse(JSON.stringify())
Класичний спосіб, який працює всюди, навіть у старих браузерах:
const user = {
name: 'Alice',
address: { city: 'Kyiv' },
tags: ['frontend', 'dev']
};
const clone = JSON.parse(JSON.stringify(user));
clone.address.city = 'Lviv';
console.log(user.address.city); // "Kyiv"Переваги:
- Просто і універсально.
Недоліки:
- Втрачає:
- функції;
undefined,Symbol,BigInt;Date,Map,Set,RegExp(перетворюються на звичайні об'єкти/рядки).
- Повільніший на дуже великих об'єктах.
3. За допомогою Lodash (_.cloneDeep())
Якщо проєкт великий або використовується TypeScript - це найнадійніший варіант.
import _ from 'lodash';
const clone = _.cloneDeep(user);Переваги:
- Глибоко копіює будь-які типи даних (включно з
Date,Map,Set,Bufferтощо). - Працює стабільно в усіх середовищах.
Недолік:
-
Потребує встановлення бібліотеки:
javascriptnpm install lodash
4. Ручна рекурсивна копія (для розуміння)
Якщо хочеш зрозуміти механіку - ось базова реалізація:
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (Array.isArray(obj)) {
return obj.map(deepClone);
}
const clone = {};
for (const key in obj) {
clone[key] = deepClone(obj[key]);
}
return clone;
}
const user = { name: 'Alice', address: { city: 'Kyiv' } };
const clone = deepClone(user);
clone.address.city = 'Lviv';
console.log(user.address.city); // "Kyiv"Працює для звичайних об'єктів і масивів,
але не для Map, Set, Date, RegExp тощо (для цього потрібен Lodash або structuredClone).
Підсумок
| Метод | Підтримка | Копіює вкладені об'єкти | Зберігає типи (Date, Map, Set) | Копіює функції |
|---|---|---|---|---|
structuredClone() | Сучасні браузери, Node 17+ | Так | Так | Ні |
JSON.parse(JSON.stringify()) | Всюди | Так | Ні | Ні |
_.cloneDeep() | Через бібліотеку Lodash | Так | Так | Ні |
| Рекурсивна функція | Ручна реалізація | Так | Ні | Ні |
В одній фразі:
Щоб зробити надійну глибоку копію, використовуй
structuredClone(obj)- якщо потрібна вбудована функція,_.cloneDeep(obj)- якщо проєкт великий і важлива стабільність.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.