Этот вопрос касается методов создания глубоких копий объектов в JavaScript и их ограничений.
Для глубокого копирования объектов используйте JSON.parse(JSON.stringify(obj)) для простых объектов, structuredClone() для современных браузеров, или библиотеки типа Lodash _.cloneDeep(). Ручная рекурсивная функция также подходит для сложных случаев. Каждый метод имеет свои ограничения и особенности.
Глубокое копирование создает полностью независимую копию объекта со всеми вложенными свойствами.
Методы копирования:
1. JSON метод (простой, но с ограничениями):
const obj = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(obj));
// Ограничения:
// - Игнорирует функции, undefined, Symbol
// - Преобразует Date в строки
// - Теряет прототипы и конструкторы2. structuredClone (современный стандарт):
// Нативный метод для глубокого копирования
const obj = { a: 1, b: { c: 2 } };
const copy = structuredClone(obj);
// Поддерживает:
// - Map, Set, Date, RegExp, ArrayBuffer
// - Циклические ссылки3. Рекурсивная функция:
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (hash.has(obj)) return hash.get(obj);
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
const clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}4. Lodash cloneDeep:
const _ = require('lodash');
const copy = _.cloneDeep(original);Пример с циклическими ссылками:
const obj = { a: 1 };
obj.self = obj;
// JSON метод упадет
// JSON.parse(JSON.stringify(obj)); // TypeError
// structuredClone работает
const copy = structuredClone(obj); // УспешноРекомендации:
Используйте structuredClone для современных приложений
Для legacy поддержки - Lodash или JSON метод
Для особых случаев - кастомную рекурсивную функцию