← Назад к вопросам

Какие знаешь способы создания копий объекта?

2.0 Middle🔥 171 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы создания копий объекта в JavaScript

Копирование объектов — фундаментальная задача в JavaScript, особенно учитывая работу с ссылочными типами данных. Существует несколько методов, которые различаются по глубине копирования и поддержке современных стандартов.

Поверхностное копирование (Shallow Copy)

Поверхностное копирование создаёт новый объект, но вложенные объекты остаются ссылками на оригинальные.

1. Оператор spread (...) (ES6+)

Наиболее популярный и лаконичный способ для простых объектов и массивов.

const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.a = 10; // Не влияет на оригинал
copy.b.c = 20; // Меняет оригинал, так как b — ссылка!

2. Object.assign()

Классический метод для копирования свойств одного объекта в другой.

const original = { x: 1, y: { z: 3 } };
const copy = Object.assign({}, original);

Важно: Object.assign также выполняет только поверхностное копирование.

3. Методы массивов для массивов объектов

Для копирования массивов объектов используются:

const arr = [{ id: 1 }, { id: 2 }];
const sliceCopy = arr.slice();
const concatCopy = [].concat(arr);
const spreadCopy = [...arr];

Глубокое копирование (Deep Copy)

Глубокое копирование рекурсивно копирует все вложенные объекты, создавая полностью независимую копию.

1. JSON.parse(JSON.stringify())

Универсальный, но ограниченный метод:

const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));

Недостатки:

  • Удаляет undefined, Symbol, функции
  • Не работает с циклическими ссылками
  • Преобразует Date в строки, Map/Set теряются

2. Рекурсивная функция

Кастомная реализация для полного контроля:

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 = new obj.constructor();
    hash.set(obj, clone);
    
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = deepClone(obj[key], hash);
        }
    }
    return clone;
}

3. structuredClone() (Modern API)

Современный нативный API для глубокого копирования:

const original = { a: 1, b: { c: 2 }, d: new Date() };
const deepCopy = structuredClone(original);

Преимущества:

  • Поддерживает циклические ссылки
  • Сохраняет типы данных (Date, Map, Set, ArrayBuffer и др.)
  • Встроенная в платформу, быстрая работа

Специализированные библиотеки

Для сложных случаев используются библиотечные реализации:

  • Lodash: _.cloneDeep() — наиболее надёжное решение в production
  • jQuery: $.extend(true, {}, obj) — для legacy-проектов

Критерии выбора метода

При выборе способа копирования учитывайте:

  1. Глубину копирования — нужна ли полная изоляция вложенных объектов?
  2. Производительность — для больших объектов structuredClone или _.cloneDeep оптимальны
  3. Поддерживаемые типы данных — работа с Map, Set, Date требует специальных методов
  4. Циклические ссылки — только structuredClone и кастомные реализации с WeakMap
  5. Браузерную поддержку — для legacy-окружений может потребоваться полифил

Практические рекомендации

  • Для простых объектов без вложенности используйте spread-оператор
  • Для полного глубокого копирования в современных браузерах применяйте structuredClone()
  • В production-проектах с complex-объектами используйте _.cloneDeep() из Lodash
  • Всегда тестируйте выбранный метод на ваших конкретных структурах данных
  • Помните о производительности при копировании больших или сложных объектов

Правильный выбор метода копирования предотвращает множество ошибок, связанных с непреднамеренным мутированием оригинальных данных, что особенно критично в React/Vue приложениях при работе с состоянием.