Ответ
Глубокое копирование создает полностью независимую копию объекта, включая все вложенные объекты. Поверхностное копирование создает новый объект, но вложенные объекты остаются ссылками на оригиналы.
Пример с поверхностным копированием:
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
shallowCopy.b.c = 3; // изменит и оригинальный obj.b.c
Пример с глубоким копированием:
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 4; // не повлияет на оригинальный obj
Методы глубокого копирования: JSON.parse(JSON.stringify()), библиотеки типа Lodash (_.cloneDeep()), рекурсивное копирование. Для поверхностного: spread-оператор, Object.assign(), Array.slice().
Ответ 18+ 🔞
О, ну ты держись, сейчас я тебе такую простыню про копирование разложу, что ты офигеешь. Сидишь ты такой, пишешь код, и тут — бац! — нужно скопировать объект. А нихуя не всё так просто, дружище.
Вот представь: есть у тебя объект, как мешок с картошкой, а внутри мешка ещё один маленький мешочек с горохом. Так вот, поверхностное копирование — это как взять новый большой мешок и пересыпать в него картошку. Но маленький мешочек с горохом ты не пересыпаешь, ты просто берёшь и кладёшь в новый мешок тот же самый маленький мешочек. Один и тот же, ёпта! Ты в новом мешке гороху насыпешь — и в старом мешке его тоже станет больше, потому что мешочек-то один! Вот это пиздец, да?
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
shallowCopy.b.c = 3; // ААА! И в оригинальном obj.b.c теперь тоже 3, блядь!
Вот так и живём. Сделал копию, думаешь — безопасно, а она тебе втихую оригинал ебёт.
А теперь глубокое копирование — это уже цирк с конями. Это когда ты берёшь и пересыпаешь ВСЁ. И картошку, и горох из маленького мешочка в новый маленький мешочек. Полная независимость, как США от Англии, только без чая в океане.
Самый народный способ, конечно, вот этот угарный костыль:
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 4; // Вот теперь всё чики-пуки, оригинал obj.b.c остался 3, иди нахуй.
Работает? Работает. Но это как молотком гвозди забивать — универсально, но не всегда изящно. Если там функции или undefined с Infinity — JSON сдохнет, как муха на стекле.
Есть ещё библиотеки, типа Lodash, у них там _.cloneDeep() — это уже профессиональный инструмент, как швейцарский нож. А можно и самому рекурсивно написать, но это уже для мазохистов, которые любят боль и страдания.
Короче, запомни, как "Отче наш": если нужно просто новый внешний контейнер — spread-оператор, Object.assign() или Array.slice(). А если нужно, чтобы всё внутри было независимым и не ебало мозг — тогда глубокое копирование, и да пребудет с тобой сила.