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

JavaScript обрабатывает копирование двумя способами в зависимости от типа данных.

Примитивные значения (копирование по значению)

К примитивным типам относятся строки, числа, логические значения (booleans), символы (symbols), bigInt и null. При копировании примитива JavaScript создает в памяти новую независимую версию.

Пример:

let a = 10;
let b = a;
b = 20;

Результат: a остается равным 10.

Непримитивные значения (копирование по ссылке)

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

Пример:

let original = { name: "YOO" };
let copy = original;
copy.name = "NEW";

Результат: original.name теперь равно "NEW".

Разница: Поверхностное против глубокого

Поверхностное копирование (Shallow copy) копирует только верхний уровень объекта. Если у объекта есть вложенные объекты, они по-прежнему будут указывать на оригинальные вложенные ссылки. Глубокое копирование (Deep copy) создает полностью новый объект со всеми новыми значениями.

Представьте, что это пицца:

  • Поверхностное копирование: Вы с другом делите одну пиццу. Если ваш друг съест кусок, пицца станет меньше и для вас тоже.
  • Глубокое копирование: У каждого из вас своя отдельная пицца. Если ваш друг съест кусок, ваша пицца останется прежней.

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

Для создания поверхностной копии можно использовать оператор расширения (...).

let original = { name: "YOO", details: { age: 22 } };
let copy = { ...original };

Внимание: Если вы измените original.details.age, то copy.details.age также изменится. Это «ловушка» поверхностного копирования.

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

1. structuredClone()

Это встроенная функция в современных браузерах и Node.js. Она идеально справляется с вложенными структурами.

Плюсы:

  • Быстрая и нативная.
  • Обрабатывает Date, RegExp и Map.

Минусы:

  • Не работает, если объект содержит функции или DOM-узлы.

2. JSON.parse(JSON.stringify())

Это старый трюк, при котором объект преобразуется в строку, а затем обратно в объект.

Почему стоит избегать:

  • Теряются такие данные, как undefined, Map, Set или Infinity.
  • Это может привести к искажению некоторых значений.

Источник: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5