How to Deep Merge Two Objects in JavaScript ?
Typically, in JavaScript, combining two objects is a commonplace thing to do, but when it involves intricate nesting, deep merging turns out to be necessary, deep merge is the activity of taking the attributes or features from multiple objects (which have nested objects) and creating a new object with merged values.
These are the following approaches:
Using Recursive Function
The recursive traveling through the items method is employed here in which properties are merged, for the deep merge for nested objects, the function calls itself.
Syntax:
function deepMerge(target, ...sources) {
// Implementation
}
Example: In the example below we will see how we can merge two objects using the Recursive Function approach.
function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
}
function deepMerge(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]: {} });
deepMerge(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return deepMerge(target, ...sources);
}
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 } };
const merged = deepMerge({}, obj1, obj2);
console.log(merged);
function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
}
function deepMerge(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]: {} });
deepMerge(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return deepMerge(target, sources);
}
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 } };
const merged = deepMerge({}, obj1, obj2);
console.log(merged);
Output
{ a: { b: 1, c: 2 } }
Using Spread Operator
Objects can be shallow copied using the spread operator (...), by combining recursion with spread operators, it is possible to obtain a deep merging of objects.
Syntax:
function deepMerge(target, ...sources) {
// Implementation
}
Example: In the example below we will see how we can merge two objects using Spread Operator approach.
function isObject(item) {
return item !== null && typeof item === 'object' && !Array.isArray(item);
}
function deepMerge(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const sourceValue = source[key];
if (isObject(sourceValue) && isObject(target[key])) {
target[key] = deepMerge(target[key], sourceValue);
} else {
target[key] = sourceValue;
}
}
}
}
return deepMerge(target, ...sources);
}
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 } };
const merged = deepMerge({}, obj1, obj2);
console.log(merged);
function isObject(item) {
return item !== null && typeof item === 'object' && !Array.isArray(item);
}
function deepMerge(target, sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const sourceValue = source[key];
if (isObject(sourceValue) && isObject(target[key])) {
target[key] = deepMerge(target[key], sourceValue);
} else {
target[key] = sourceValue;
}
}
}
}
return deepMerge(target, sources);
}
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 } };
const merged = deepMerge({}, obj1, obj2);
console.log(merged);
Output
{ a: { b: 1, c: 2 } }
Using Libraries like Lodash
Lodash has a merge function that does deep merging of objects, it handles its edge cases and complexities very well which makes it a dependable choice for deep merging.
Syntax:
import _ from 'lodash';
const mergedObject = _.merge(object1, object2);
Example: In the example below we will see how we can merge two objects using Libraries like Lodash.
import _ from 'lodash';
const obj1 = { a: { b: 1 } };
const obj2 = { a: { c: 2 } };
const merged = _.merge(obj1, obj2);
console.log(merged);
Output:
{ a: { b: 1, c: 2 } }