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

Что такое копии объекта?

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

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

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

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

Что такое копии объекта?

В JavaScript под копиями объекта подразумеваются способы создания нового объекта, который повторяет структуру и данные исходного объекта. Это фундаментальное понятие, поскольку объекты в JavaScript являются ссылочными типами данных, в отличие от примитивов (строк, чисел, boolean), которые копируются по значению. Когда вы присваиваете переменную, содержащую объект, другой переменной, вы копируете не сам объект, а ссылку на него в памяти. Обе переменные начинают указывать на один и тот же объект, и изменения через одну переменную мгновенно отражаются на другой.

Пример проблемы ссылочного копирования

const original = { a: 1, b: { c: 2 } };
const copy = original; // Копируется только ссылка!

copy.a = 99;
console.log(original.a); // 99! Изменение в `copy` затронуло `original`.

copy.b.c = 100;
console.log(original.b.c); // 100. Вложенный объект тоже изменён.

Для создания независимых дубликатов используются два основных подхода: поверхностное (shallow) и глубокое (deep) копирование.

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

Поверхностное копирование создаёт новый объект, который на верхнем уровне содержит те же пары ключ-значение, что и исходный. Однако, если значением свойства является вложенный объект (или массив, функция и т.д.), в новый объект копируется ссылка на этот вложенный объект, а не он сам. Изменения вложенных объектов в копии будут влиять на оригинал и наоборот.

Методы поверхностного копирования:

  • Spread оператор (...) — современный и наиболее популярный способ.

    const original = { a: 1, b: { c: 2 } };
    const shallowCopy = { ...original };
    
  • Object.assign() — классический метод.

    const shallowCopy = Object.assign({}, original);
    
  • Array.prototype.slice() (для массивов).

    const arr = [1, 2, { x: 3 }];
    const arrCopy = arr.slice();
    

Ограничение поверхностной копии:

shallowCopy.a = 999; // Не влияет на оригинал: `original.a` останется 1.
shallowCopy.b.c = 888; // Меняет и оригинал! `original.b.c` станет 888.

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

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

Методы глубокого копирования:

  • JSON.parse(JSON.stringify(obj)) — самый быстрый и простой способ, но с серьёзными ограничениями.
    const deepCopy = JSON.parse(JSON.stringify(original));
    
    **Недостатки этого метода:**
    *   Игнорирует свойства со значениями `undefined`, `Symbol` и функциями.
    *   Преобразует (и часто ломает) специальные типы, такие как `Date` (в строку), `Map`, `Set`, `RegExp`.
    *   Не может копировать циклические ссылки (когда объект ссылается сам на себя).

  • Использование сторонних библиотек. Наиболее надёжный способ в production.
    *   **`lodash`** — функция `_.cloneDeep()`.
    ```javascript
    import _ from 'lodash';
    const deepCopy = _.cloneDeep(original);
    ```
    *   **`structuredClone()`** — нативная глобальная функция, появившаяся в современных браузерах и Node.js.
    ```javascript
    const deepCopy = structuredClone(original);
    ```
        Она корректно обрабатывает многие сложные типы и циклические ссылки, но также не копирует функции, DOM-узлы и прототипы.

Когда что использовать?

  • Не копировать (использовать ссылку): когда вам действительно нужно, чтобы несколько частей кода работали с одним и тем же экземпляром объекта (например, глобальное состояние).
  • Поверхностное копирование: когда объект простой (нет вложенных объектов или массивов) или когда разделение ссылок на вложенные объекты является осознанным поведением.
  • Глубокое копирование: когда необходимо создать полный, изолированный "снимок" состояния сложного объекта, например, перед выполнением рискованных операций, для управления неизменяемым состоянием в Redux или при отправке данных через API, чтобы избежать случайных мутаций.

Понимание различий между типами копирования критически важно для предотвращения трудноуловимых багов, связанных с неожиданными мутациями данных, и является краеугольным камнем для работы с современными state-менеджерами и функциональным программированием во фронтенд-разработке.

Что такое копии объекта? | PrepBro