Как глубоко объединить объекты JavaScript?
Метод Object.assign
или оператор распространения позволяет нам мелкие слияния объектов JavaScript.
Это означает, что объединяется только первый уровень, но более глубокие уровни по-прежнему ссылаются на исходный объект.
Глубокое слияние гарантирует, что все уровни объектов, которые мы объединяем в другой объект, будут скопированы вместо того, чтобы ссылаться на исходные объекты.
В этой статье мы рассмотрим, как выполнить глубокое слияние объектов JavaScript.
Рекурсивное слияние
Для глубокого объединения объектов JavaScript мы должны сами рекурсивно объединить каждый уровень.
Для этого нам нужно написать собственную функцию.
Например, мы можем написать:
const isObject = (item) => {
return (item && typeof item === 'object' && !Array.isArray(item));
}
const mergeDeep = (target, ...sources) => {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, {
[key]: {}
});
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, {
[key]: source[key]
});
}
}
}
return mergeDeep(target, ...sources);
}
const merged = mergeDeep({
a: 1
}, {
b: {
c: 123
}
});
console.log(merged)
Сначала мы создаем вспомогательную функцию isObject
, проверяя, является ли параметр item
истинным и является ли объект не массивом.
Мы используем оператор typeof
, чтобы проверить, является ли объект объектом.
Если это правда и его тип - объект, то это должен быть объект.
Затем мы проверяем, не является ли объект массивом, с помощью метода Array.isArray
.
Затем мы создаем метод mergeDeep
для объединения нескольких объектов в объект target
.
Для этого мы сначала проверяем, хранится ли что-нибудь в sources
.
Если его нет, то мы возвращаем объект target
, поскольку второго и последующих аргументов нет.
Затем мы проверяем, являются ли target
и source
объектами.
Мы получаем source
, получая первый элемент из массива source
с помощью shift
.
Мы перебираем ключи source
с помощью цикла for-in.
Если свойство является объектом, то мы объединяем пустой объект в объект target
с помощью Object.assign
.
Затем мы вызываем mergeDeep
рекурсивно объединяя ключи внутри свойства объекта source
в объект.
В противном случае у нас есть примитивное значение свойства, и мы вызываем Object.assign
для непосредственного слияния с объектом.
Наконец, в конце мы возвращаем объединенный объект.
Затем мы пробуем еще раз, вызывая mergeDeep
с 2 объектами.
И мы должны увидеть, что merged
это:
{
"a": 1,
"b": {
"c": 123
}
}
Метод слияния Lodash
Если мы не хотим писать нашу собственную функцию, мы можем использовать Lodash метод merge
для объединения объектов.
Например, мы можем написать:
const merged = _.merge ({
a: 1
}, {
b: {
c: 123
}
});
И мы получаем такое же значение для merged
.