Best Solution: Object.assign()
The Object.assign()
method is the most straightforward way to merge objects in JavaScript. It copies the values (primitive and functions) and symbols from one or more source objects to a target object. It returns the target object.
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
let mergedObj = Object.assign(obj1, obj2);
console.log(mergedObj); // Output: { a: 1, b: 3, c: 4 }
In this example, obj2
overwrites the property b
in obj1
because Object.assign()
merges objects from left to right. However, it’s important to note that Object.assign()
performs a shallow copy, which means that it won’t clone child objects.
The Spread Operator
Introduced in ES6, the spread operator (...
) provides a quick and concise way to merge objects.
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
let mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // Output: { a: 1, b: 3, c: 4 }
Like Object.assign()
, the spread operator performs a shallow merge and later properties overwrite earlier ones.
Merge Array of Objects using reduce() and Object.assign()
The reduce()
method applies a function to each item in an array, in order, to reduce the array to a single output value. We can use it with Object.assign()
to merge an array of objects.
let arr = [{ a: 1 }, { b: 2 }, { c: 3 }];
let mergedObj = arr.reduce((accumulator, obj) => Object.assign(accumulator, obj), {});
console.log(mergedObj); // Output: { a: 1, b: 2, c: 3 }
In this example, arr.reduce()
iterates over each object in arr
and merges it into accumulator
using Object.assign()
.
How To Deep Merge Nested Objects
In JavaScript, there are no built-in functions that you can use to deeply merge 2 or more nested objects. But if your use case is simple enough, you can use a custom function like the one I wrote below. This function will handle nested objects, but it won’t handle circular references, arrays, or other non-plain object data types.
function deepMerge(obj1, obj2) {
let output = {...obj1};
for (let key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (typeof obj2[key] === 'object' && obj2[key] !== null && obj1[key]) {
output[key] = deepMerge(obj1[key], obj2[key]);
} else {
output[key] = obj2[key];
}
}
}
return output;
}
// Usage
let obj1 = { a: 1, b: { x: 2 } };
let obj2 = { b: { y: 3 }, c: 4 };
let mergedObj = deepMerge(obj1, obj2);
console.log(mergedObj); // Output: { a: 1, b: { x: 2, y: 3 }, c: 4 }
In this function, I start by creating a shallow copy (output
) of the first object (obj1
). Then I loop through each property (key
) in the second object (obj2
).
If the property is an object and it exists in obj1
, I call deepMerge()
recursively to merge the two nested objects and assign the result to output[key]
. Otherwise, I simply copy the property from obj2
to output
.
This function is a simple example and may not cover all edge cases. For more complex scenarios, consider using a utility library like Lodash, which provides a robust _.merge()
function that handles a wider variety of data types and edge cases.
Let’s further explore the libraries option.
Deep Merge Objects using a Library
The _.merge() Method from Lodash
Lodash is a popular utility library that provides helpful methods for the manipulation and combination of arrays, objects, and other JavaScript data types. One such method is _.merge()
, which is similar to Object.assign()
, but it performs a deep copy, meaning it can handle child objects.
let _ = require('lodash');
let obj1 = { a: 1, b: { x: 2 } };
let obj2 = { b: { y: 3 }, c: 4 };
let mergedObj = _.merge({}, obj1, obj2);
console.log(mergedObj); // Output: { a: 1, b: { x: 2, y: 3 }, c: 4 }
In this example, _.merge()
merges the properties of obj1
and obj2
into a new object, preserving nested objects.
The $.extend() Method from jQuery
If you’re working with jQuery, you can use the $.extend()
method to merge objects. By default, $.extend()
performs a shallow copy. However, if you pass true
as the first argument, it performs a deep copy.
let obj1 = { a: 1, b: { x: 2 } };
let obj2 = { b: { y: 3 }, c: 4 };
let mergedObj = $.extend(true, {}, obj1, obj2);
console.log(mergedObj); // Output: { a: 1, b: { x: 2, y: 3 }, c: 4 }
This example demonstrates a deep merge using $.extend()
. The {}
is an empty target object, ensuring we don’t modify obj1
or obj2
.
Final words
Each method has its own strengths and weaknesses. Object.assign()
and the spread operator are simple and clear, but they only perform shallow merges. Lodash’s _.merge()
and jQuery’s $.extend()
are more powerful and can handle deep merges, but they require an external library. The reduce()
and Object.assign()
method is flexible and doesn’t require external libraries, the same goes for my custom deepMerge()
function, but they may be harder to understand for beginners.
In conclusion, there are several ways to merge objects in JavaScript, each with its own trade-offs. It’s crucial to understand these methods and choose the right one based on your specific needs.