JS Intermediate

Копирование объектов

Понять разницу между примитивами (копируются по значению) и объектами (передаются по ссылке), и научиться создавать shallow и deep копии.

Средний (Intermediate)
Нужно знать:Объекты

Кратко

Примитивы копируются по значению: const b = a — создаёт копию. Объекты передаются по ссылке: const b = a — обе переменные указывают на тот же объект. Spread {...obj} создаёт поверхностную копию. structuredClone(obj) — глубокую.


Подробно

Примитивы vs Объекты:

Примитивы (number, string, boolean, null, undefined): const a = 5; const b = a; // b = 5 (копия) b = 10; console.log(a); // 5 (а не изменилась)

Объекты (objects, arrays, functions): const obj1 = { x: 1 }; const obj2 = obj1; // obj2 = ссылка на тот же объект obj2.x = 2; console.log(obj1.x); // 2 (изменился и obj1!)

Почему так? Объект живёт в памяти. Переменная obj1 — это «указатель» на этот объект. const obj2 = obj1 копирует указатель, а не сам объект.

Shallow copy (поверхностная): const original = { a: 1, b: { c: 2 } }; const copy = { ...original };

copy.a = 100; console.log(original.a); // 1 (не изменился)

copy.b.c = 200; console.log(original.b.c); // 200 (изменился!)

Spread копирует только верхний уровень. Вложенные объекты — ссылки.

Deep copy (глубокая): const deepCopy = structuredClone(original); // structuredClone рекурсивно копирует все уровни

Другие способы:

  • JSON.parse(JSON.stringify(obj)) — ограничения: теряет undefined, функции, Date
  • structuredClone() — современный, поддерживает Date, Map, Set
  • Лучше structuredClone для большинства случаев

Ментальная модель

Shallow copy — как сфотографировать дом. Вы видите фотографию (копию), но мебель внутри — та же самая (ссылки на те же объекты). Deep copy — как построить точную Replica дома со всей мебелью.


Примеры

**Самый простой:**

javascript
const a = 5;
const b = a;
b = 10;
console.log(a); // 5 (примитив — копия)

const obj1 = { x: 1 };
const obj2 = obj1;
obj2.x = 2;
console.log(obj1.x); // 2 (объект — ссылка)

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

**Простой:**

javascript
const original = { name: 'Анна', scores: [90, 85] };
const shallow = { ...original };
const deep = structuredClone(original);

shallow.name = 'Пётр';
console.log(original.name); // 'Анна' (не изменился)

shallow.scores.push(95);
console.log(original.scores); // [90, 85, 95] (изменился!)

deep.scores.push(80);
console.log(original.scores); // [90, 85, 95] (не изменился!)

Spread — поверхностная копия (shallow copy). structuredClone — глубокая копия (deep copy).

**Реальный пример:**

javascript
function mergeDefaults(user, defaults) {
  // structuredClone чтобы не мутировать defaults
  const result = structuredClone(defaults);
  return { ...result, ...user };
}

const defaults = { theme: 'dark', lang: 'ru', notifications: true };
const userPrefs = { theme: 'light' };

const settings = mergeDefaults(userPrefs, defaults);
console.log(settings);
// { theme: 'light', lang: 'ru', notifications: true }
console.log(defaults.theme); // 'dark' (не мутирован!)

Merge с глубоким клонированием предотвращает мутиацию оригиналов.


Частые ошибки

**Неправильно:** Думать, что spread создаёт глубокую копию

**Почему:** Spread {...obj} копирует только верхний уровень. Вложенные объекты — ссылки.

**Правильно:** Для глубокой копии: structuredClone(obj).

**Неправильно:** Использовать JSON.parse(JSON.stringify()) для копирования

**Почему:** Теряет undefined, функции, Date, Map, Set, циклические ссылки.

**Правильно:** Используйте structuredClone() — он поддерживает больше типов.

**Неправильно:** Путать копирование и клонирование массивов

**Почему:** [...arr] — поверхностная копия (shallow copy). structuredClone(arr) — глубокая копия (deep copy).

**Правильно:** Для простых массивов [...arr] достаточно. Для вложенных — structuredClone.


Важно запомнить

  • Примитивы — копируются по значению
  • Объекты — передаются по ссылке
  • Spread {...obj} — shallow copy
  • structuredClone(obj) — deep copy
  • JSON.parse(JSON.stringify()) — есть ограничения

Связь

Назад: Вы знаете объекты (J11) — теперь вы понимаете, как их копировать.

Вперёд: Следующий урок (JI4) — методы объекта и ключевое слово this.

Материалы курса JS Intermediate — PROlab Academy.