Глубокое и поверхностное копирование в JavaScript

В этой статье мы разберем, что собой представляют глубокое и поверхностное копирование, рассмотрим методы их реализации, обсудим их преимущества и недостатки, а также практическое применение. Запись Глубокое и поверхностное копирование в JavaScript впервые появилась techrocks.ru.

Jan 14, 2025 - 14:46
Глубокое и поверхностное копирование в JavaScript

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

Глубокое копирование в сравнении с поверхностным

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

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

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

Использование JSON.stringify и JSON.parse

function deepClone(obj) {
    return JSON.parse(JSON.stringify(obj));
}
  • Плюсы: простота и эффективность для базовых структур данных.
  • Минусы: не работает с такими объектами, как Date или RegExp, и круговыми ссылками.

Рекурсия

function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) return obj;
    const clone = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) clone[key] = deepClone(obj[key]);
    }
    return clone;
}
  • Плюсы: с помощью дополнительной логики справляется с пользовательскими типами объектов и круговыми ссылками.
  • Минусы: более сложная реализация.

Использование structuredClone

const clonedObj = structuredClone(originalObj);
  • Плюсы: встроенная поддержка в современных браузерах для глубокого копирования сложных типов.
  • Минусы: недоступно в старых браузерах.

Сторонние библиотеки (например, Lodash)

import cloneDeep from 'lodash/cloneDeep';
const clonedObj = cloneDeep(originalObj);
  • Плюсы: оптимизация для крайних случаев, поддержка круговых ссылок.
  • Минусы: добавление зависимостей.

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

slice() или concat()

const shallowCopy = originalArray.slice();
const shallowCopy2 = originalArray.concat();

Spread-оператор (…)

const shallowCopy = [...originalArray];

Array.from()

const shallowCopy = Array.from(originalArray);

Важное замечание: изменения вложенных объектов в поверхностной копии влияют на оригинал.

Что следует иметь в виду

Круговые ссылки. Методы глубокого копирования, такие как рекурсия или библиотеки, справляются с круговыми ссылками лучше, чем JSON.stringify.

Производительность. Глубокое копирование больших или сложных объектов может быть ресурсоемким.

Специальные объекты. Специальные типы (например, Date, RegExp) требуют особой обработки для точного копирования.

Разобравшись в глубоком и поверхностном копировании, вы сможете ситуативно выбирать наилучшую технику для ваших нужд, уравновешивая производительность, совместимость и сложность.

Перевод статьи “How to Implement and Use Deep Copy and Shallow Copy in JavaScript”.

Запись Глубокое и поверхностное копирование в JavaScript впервые появилась techrocks.ru.