Avatar ·

Как объединить свойства двух JavaScript объектов в один?

Всем привет! Я новичок в JavaScript и столкнулся с такой задачей: у меня есть два объекта с данными, и мне нужно объединить их свойства в один объект. Например, есть объект `user` с именем и возрастом, и объект `address` с городом и улицей. Я хочу получить один объект, который содержит все свойства из обоих объектов. Вот пример кода: ```javascript const user = { name: 'Иван', age: 30 }; const address = { city: 'Москва', street: 'Тверская' }; // Как получить объект, который выглядит так: // { // name: 'Иван', // age: 30, // city: 'Москва', // street: 'Тверская' // } ``` Я пробовал просто складывать объекты через оператор `+`, но это не работает — получается строка. Пытался использовать `Object.assign()`, но не совсем понял, как это правильно делать. Ещё слышал про spread оператор (`...`), но не уверен, подходит ли он для объектов. Подскажите, пожалуйста, как правильно объединить свойства объектов? Важно, чтобы при совпадении ключей (например, если в обоих объектах есть свойство `id`) значение бралось из второго объекта. Заранее спасибо! <<>>

Способы объединения объектов в JavaScript

Для объединения свойств двух или более объектов в JavaScript существует несколько подходов. Рассмотрим самые популярные и правильные из них.

1. Spread оператор (рекомендуемый способ)

Самый современный и лаконичный способ — использовать spread оператор .... Он работает с объектами начиная с ES2018 (ES9).

const user = {
  name: 'Иван',
  age: 30
};

const address = {
  city: 'Москва',
  street: 'Тверская'
};

const merged = { ...user, ...address };

console.log(merged);
// { name: 'Иван', age: 30, city: 'Москва', street: 'Тверская' }

Важное преимущество: если в объектах есть одинаковые ключи, последний переданный объект перезаписывает предыдущие значения. Это работает как раз так, как вы хотели:

const obj1 = { id: 1, name: 'Анна' };
const obj2 = { id: 2, city: 'СПб' };

const result = { ...obj1, ...obj2 };
console.log(result); // { id: 2, name: 'Анна', city: 'СПб' }

2. Object.assign()

Классический метод, доступный во всех версиях ES6+. Он копирует свойства из исходных объектов в целевой объект.

const merged = Object.assign({}, user, address);

console.log(merged);
// { name: 'Иван', age: 30, city: 'Москва', street: 'Тверская' }

Важно: первый аргумент — это целевой объект. Если передать пустой объект {}, то исходные объекты не изменятся. Если передать существующий объект, он мутирует:

const target = { country: 'Россия' };
Object.assign(target, user, address);
console.log(target); // target изменился, теперь содержит свойства из user и address

Правило перезаписи такое же: последний объект имеет приоритет при совпадении ключей.

3. Цикл for...in (устаревший способ)

Можно объединять вручную, но это не рекомендуется, если есть современные альтернативы:

const merged = {};

for (let key in user) {
  merged[key] = user[key];
}
for (let key in address) {
  merged[key] = address[key];
}

console.log(merged); // тот же результат

Что выбрать?

  • Spread оператор { ...a, ...b } — лучший выбор для современного кода. Коротко, читаемо, не мутирует исходные объекты.
  • Object.assign() — если нужно поддерживать старые браузеры (IE) или работать в среде, где spread для объектов недоступен.
  • Цикл — только если нужно добавить дополнительную логику при копировании (например, фильтрацию или трансформацию).

Важные замечания

Оба способа выполняют поверхностное копирование (shallow copy). Если свойства объектов — это вложенные объекты или массивы, они будут скопированы по ссылке:

const a = { nested: { value: 1 } };
const b = { other: 2 };
const c = { ...a, ...b };

c.nested.value = 999;
console.log(a.nested.value); // 999 — исходный объект изменился!

Для глубокого копирования с объединением используйте structuredClone() или библиотеки типа Lodash (_.merge()).

Надеюсь, теперь всё стало понятно! Используйте spread оператор — это современный и элегантный способ решить вашу задачу.

<<>>

Альтернативный подход: использование функции-утилиты

Если вам нужно часто объединять объекты и вы хотите иметь больше контроля над процессом, можно написать небольшую функцию-утилиту. Это особенно полезно, когда нужно обрабатывать конфликты ключей нестандартным образом (например, не просто перезаписывать, а суммировать значения).

function mergeObjects(target, ...sources) {
  const result = { ...target };
  
  for (const source of sources) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        // Здесь можно добавить свою логику
        // Например, если оба объекта имеют числовое свойство 'count'
        if (typeof result[key] === 'number' && typeof source[key] === 'number') {
          result[key] += source[key]; // суммируем вместо перезаписи
        } else {
          result[key] = source[key]; // обычная перезапись
        }
      }
    }
  }
  
  return result;
}

// Пример использования:
const cart1 = { apples: 3, oranges: 2 };
const cart2 = { apples: 1, bananas: 4 };

const totalCart = mergeObjects(cart1, cart2);
console.log(totalCart); // { apples: 4, oranges: 2, bananas: 4 }

Такой подход даёт гибкость: вы можете легко изменить поведение для конкретных типов данных или ключей. Кроме того, функция принимает любое количество объектов для объединения, что удобно при работе с несколькими источниками данных.