The Object.assign
method or the spread operator lets us shallow merge JavaScript objects.
This means that only the first level is merged but the deeper are levels are still referencing the original object.
Deep merging ensures that all levels of the objects we merge into another object are copied instead of referencing the original objects.
In this article, we’ll look at how to deep merge JavaScript objects.
Merging Recursively
To deep merge JavaScript objects, we’ve to merge each level recursively ourselves.
To do this, we’ve to write our own function.
For example, we can write:
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)
First, we create the isObject
helper function by checking if the item
parameter is truthy and it’s an object that’s not an array.
We use the typeof
operator to check if the object is an object.
If it’s truthy and its type is an object, then it must be an object.
Then we check that the object isn’t an array by using the Array.isArray
method.
Next, we create the mergeDeep
method to merge multiple objects into the target
object.
To do this, we first check if there’re anything stored in sources
.
If there’s none, then we return the target
object since there’s no 2nd and subsequent arguments.
Next, we check if target
and source
are objects.
We get source
by getting the first item from the source
array with shift
.
We loop through the keys of source
with the for-in loop.
If the property is an object, then we merge an empty object into the target
object with Object.assign
.
Then we call mergeDeep
to merge the keys inside the object property of source
into the object recursively.
Otherwise, we have a primitive property value, and we call Object.assign
to merge it into the object directly.
Finally, we return the merged object at the end.
Next, we try it by calling mergeDeep
with 2 objects.
And we should see that merged
is:
{
"a": 1,
"b": {
"c": 123
}
}
Lodash merge Method
If we don’t want to write our own function, then we can use the Lodash merge
method to merge objects.
For instance, we can write:
const merged = _.merge({
a: 1
}, {
b: {
c: 123
}
});
And we get the same value for merged
.
Conclusion
We can deep merge JavaScript objects with our own JavaScript function or the Lodash merge
method.