Зарегистрируйтесь, чтобы продолжить обучение

Слияние JS: Объекты

Слияние (merge) — операция над объектами, выполняющая их объединение. Она появляется там, где необходимо данные одного объекта перенести в другой объект.

Слияние часто используется при работе с веб-формами. Например, когда пользователь меняет свои персональные данные в настройках аккаунта, измененные данные приходят в приложение в виде объекта. Данные из этого объекта нужно перенести в объект пользователя. Так происходит обновление пользователя:

// Такой пользователь есть в системе
const user = { name: 'Tirion', email: 'support@hexlet.io', age: 44 }

// Из формы пришли данные
const data = { name: 'Tirion 2', age: 33 }

// В результате должно получиться
// { name: 'Tirion 2', email: 'support@hexlet.io', age: 33 };

Решение в лоб — перенести каждое свойство отдельно:

user.name = data.name
user.age = data.age

// Где-то тут сохраняем пользователя в базе данных

Прямой перенос хорошо работает, когда данных мало и их структура не меняется. Если же данных много или в разные моменты времени могут приходить разные данные, то это превращается в кучу одинакового кода:

if (Object.hasOwn(data, 'name')) {
  user.name = data.name
}

// И так нужно перечислить все возможные свойства

С помощью слияния (часто говорят «мержа») мы можем сократить все до одной строчки:

Object.assign(user, data)
console.log(user)
// => { name: 'Tirion 2', email: 'support@hexlet.io', age: 33 };

Метод Object.assign() берёт объект, переданный первым параметром, и переносит в него всё из объектов, переданных остальными параметрами. В нашей ситуации это один объект, переданный вторым параметром.

Слияние работает так. Если какое-то свойство было только в первом объекте, то оно остается тем, что и было. Если свойство присутствует во втором (и далее) объекте, то оно записывается в первый независимо от того, было оно там или нет. Поэтому, если свойство присутствовало и в первом объекте и во втором, то оно будет перезаписано значением из второго объекта:

const obj1 = { a: 'a', b: 'b' }
const obj2 = { c: 'c', b: 'v' }
Object.assign(obj1, obj2)
console.log(obj1)
// => { a: 'a', b: 'v', c: 'c' }

У метода Object.assign() есть одно ограничение: он выполняет только поверхностное слияние. Вложенные объекты не сравниваются, а просто заменяются:

const obj1 = { a: { a: 1 } }
const obj2 = { a: { b: 1 } }
Object.assign(obj1, obj2)
console.log(obj1)
// => { a: { b: 1 } }

// пример глубокого (рекурсивного) слияния
// используется метод merge() библиотеки lodash
import _ from 'lodash'
_.merge(obj1, obj2)
// => { a: { a: 1, b: 1 } }

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

Если говорить про веб-формы, то технически всегда можно послать больше данных, чем описано в форме.


Дополнительные материалы

  1. Метод has из библиотеки Lodash
  2. Метод merge из библиотеки Lodash

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff