Копирование и слияние объектов
Копирование и слияние объектов
Технический фундамент копирования
В JS есть принципиальная разница между:
- копией ссылки (
const b = a); - поверхностной копией (
{ ...a },Object.assign).
const a = { x: 1 };
const byRef = a;
const byCopy = { ...a };
byRef.x = 2;
console.log(a.x); // 2
console.log(byCopy.x); // 1
Ключевой момент: при работе со state и конфигами почти всегда нужна копия объекта, а не вторая ссылка.
Ошибка новичка: присваивание вместо копии
const original = { name: 'Ann', age: 20 };
const copy = original;
copy.age = 21;
console.log(original.age); // 21
Проверь себя: почему изменился original, хотя мы меняли copy?
Поверхностная копия: spread
const user = { name: 'Max', age: 25 };
const cloned = { ...user };
cloned.age = 26;
console.log(user.age); // 25
Object.assign
const base = { theme: 'light' };
const result = Object.assign({}, base, { lang: 'ru' });
console.log(result); // { theme: 'light', lang: 'ru' }
Object.assign и spread делают поверхностную копию.
Смотри, что важно: Object.assign(target, ...) мутирует target и возвращает его же.
Поэтому для копии обычно передают пустой объект {} как target.
Слияние объектов
const defaults = { page: 1, pageSize: 20 };
const query = { pageSize: 50, search: 'js' };
const merged = { ...defaults, ...query };
console.log(merged); // { page: 1, pageSize: 50, search: 'js' }
Ключевой момент: при одинаковых ключах побеждает объект справа.
Важный edge case: вложенные объекты
const a = { profile: { city: 'Minsk' } };
const b = { ...a };
b.profile.city = 'Warsaw';
console.log(a.profile.city); // Warsaw
Это происходит из-за поверхностного копирования.
Микро-сценарии
- Обновление настроек пользователя без мутации исходника.
- Сбор итогового конфига из default + пользовательских параметров.
Типичные ошибки
- Путать «копию объекта» и «копию ссылки».
- Не учитывать вложенные структуры.
- Неверно рассчитывать приоритет при слиянии.
- Мутировать входящие данные функции.
Краткий итог
- Присваивание не копирует объект, а копирует ссылку.
- Spread и
Object.assignсоздают поверхностную копию. - Слияние удобно делать через
{ ...a, ...b }. - При конфликте ключей побеждает правый объект.
- Для вложенных структур нужна отдельная стратегия deep copy.
Например: