Назад к вопросам
Middle
448
questionbank

Какие способы клонирования объектов ты знаешь?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

  • Поверхностное (Shallow copy)
  • Глубокое (Deep copy)

Поверхностное клонирование:

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

Способы:

  • Спред-оператор (...)
  • Object.assign()
// Пример с спред-оператором
const original = { a: 1, b: { c: 2 } };
const shallowCopySpread = { ...original };
// Изменение вложенного объекта в копии
shallowCopySpread.b.c = 3;
console.log(original.b.c); // Выведет 3 - изменение отразилось в оригинале
// Пример с Object.assign
const original = { a: 1, b: { c: 2 } };
const shallowCopyAssign = Object.assign({}, original);
// Изменение вложенного объекта в копии
shallowCopyAssign.b.c = 4;
console.log(original.b.c); // Выведет 4 - изменение отразилось в оригинале

Глубокое клонирование:

  • Клонируется сам объект и все его вложенные объекты рекурсивно.
  • Изменения в клоне не влияют на оригинал, и наоборот.

Способы:

  • JSON.parse(JSON.stringify()) (имеет ограничения, например, не клонирует функции, Date, RegExp, undefined, Infinity, NaN, Map, Set)
  • Библиотеки (например, Lodash - _.cloneDeep())
  • Рекурсивная функция (для более точного контроля)
// Пример с JSON.parse(JSON.stringify())
const original = { a: 1, b: { c: 2 }, d: () => {} }; // Функция не клонируется
const deepCopyJSON = JSON.parse(JSON.stringify(original));
// Изменение вложенного объекта в копии
deepCopyJSON.b.c = 5;
console.log(original.b.c); // Выведет 4 - изменение не отразилось в оригинале
console.log(deepCopyJSON.d); // Выведет undefined
// Пример с рекурсивной функцией (простой вариант)
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  let copy = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      copy[key] = deepClone(obj[key]);
    }
  }

  return copy;
}

const original = { a: 1, b: { c: 2 } };
const deepCopyManual = deepClone(original);
// Изменение вложенного объекта в копии
deepCopyManual.b.c = 6;
console.log(original.b.c); // Выведет 4 - изменение не отразилось в оригинале

Сравнение:

Характеристика Поверхностное клонирование Глубокое клонирование
Вложенные объекты Ссылки на оригинальные объекты Клонируются рекурсивно
Влияние изменений Изменения во вложенных объектах взаимны Изменения в клоне не влияют на оригинал
Производительность Быстрее (не нужно рекурсивно обходить все) Медленнее (требует рекурсивного обхода)
Сложность реализации Проще (спред-оператор, Object.assign) Сложнее (рекурсивная функция, библиотеки)
Использование Когда вложенные объекты не нужно полностью изолировать Когда требуется полная независимость клона от оригинала