Question
How to Merge JavaScript Objects: Object.assign, Spread Syntax, and Practical Patterns
Question
I need to merge two simple JavaScript objects at runtime. For example:
var obj1 = { food: 'pizza', car: 'ford' };
var obj2 = { animal: 'dog' };
// Desired result: obj1 should end up with food, car, and animal
Is there a built-in way to combine the properties of one object into another in JavaScript?
I do not need deep recursion, and I do not need to merge functions. I only need to work with flat objects and copy their properties.
Short Answer
By the end of this page, you will understand how to merge flat JavaScript objects using built-in tools such as Object.assign() and object spread syntax. You will also learn what happens when property names conflict, when the original object is mutated, and which approach is most common in modern JavaScript.
Concept
In JavaScript, objects store data as key-value pairs. Merging objects means taking the properties from one object and copying them into another object.
For flat objects, this is straightforward:
- Read the properties from a source object
- Copy them onto a target object
- If the same property exists in both, the later value usually replaces the earlier one
This matters because object merging is a very common task in real programs. Developers use it to:
- combine configuration settings
- update application state
- build API request options
- add default values to user input
JavaScript provides built-in ways to do this:
Object.assign()- object spread syntax:
{ ...obj1, ...obj2 }
These are ideal for shallow merges. A shallow merge means only the top-level properties are copied. If a property contains another object or array, the inner value is not deeply merged.
In your case, since the objects are simple and flat, a shallow merge is exactly what you need.
Mental Model
Think of each object as a small label sheet.
obj1has labels:food,carobj2has label:animal
Merging means taking the labels from the second sheet and placing them onto the first sheet.
If both sheets have the same label name, the new label covers the old one.
So object merging is like combining two sets of named fields into one final set.
Syntax and Examples
Using Object.assign()
const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };
Object.assign(obj1, obj2);
console.log(obj1);
// { food: 'pizza', car: 'ford', animal: 'dog' }
Object.assign(target, source) copies the enumerable properties from the source object into the target object.
obj1is the targetobj2is the sourceobj1is changed directly
Creating a new merged object
If you do not want to change the original object:
const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };
const merged = .({}, obj1, obj2);
.(merged);
.(obj1);
Step by Step Execution
Consider this example:
const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };
const merged = Object.assign({}, obj1, obj2);
Step by step:
-
const obj1 = ...- JavaScript creates an object with two properties:
food: 'pizza'car: 'ford'
-
const obj2 = ...- JavaScript creates another object with one property:
animal: 'dog'
-
Object.assign({}, obj1, obj2)- JavaScript starts with an empty object
{} - It copies properties from
obj1into it - The object becomes:
{ : , : } - JavaScript starts with an empty object
Real World Use Cases
1. Default settings plus user settings
const defaults = { theme: 'light', notifications: true };
const userSettings = { theme: 'dark' };
const settings = { ...defaults, ...userSettings };
This keeps default values but lets user choices override them.
2. Building API request options
const baseOptions = { method: 'GET', headers: { Accept: 'application/json' } };
const authOptions = { token: 'abc123' };
const options = { ...baseOptions, ...authOptions };
This is common when preparing request objects.
3. Updating state in frontend apps
const state = { loading: true, data: null };
const nextState = { ...state, loading: false, data: [1, 2, ] };
Real Codebase Usage
In real projects, developers usually merge objects in a few standard ways.
Merging defaults with overrides
const defaultConfig = {
timeout: 5000,
retries: 2
};
function createConfig(customConfig) {
return { ...defaultConfig, ...customConfig };
}
This pattern is everywhere in libraries and application setup.
Using immutable updates
Instead of changing an existing object, many codebases create a new one:
const updatedUser = { ...user, isAdmin: true };
This is safer in state management because it avoids accidental side effects.
Guarding against missing values
Developers often check that inputs are objects before merging:
function mergeFlatObjects(a, b) {
if (!a || typeof a !== 'object') return b;
if (!b || typeof b !== 'object') return a;
{ ...a, ...b };
}
Common Mistakes
1. Expecting a custom .merge() method to exist
This will not work on normal JavaScript objects:
const obj1 = { food: 'pizza' };
const obj2 = { animal: 'dog' };
obj1.merge(obj2); // Error
Plain objects do not have a built-in .merge() method.
Use:
Object.assign(obj1, obj2);
or:
const merged = { ...obj1, ...obj2 };
2. Forgetting that Object.assign() can mutate the target
const obj1 = { a: 1 };
const obj2 = { b: 2 };
Object.assign(obj1, obj2);
console.log(obj1);
Comparisons
| Approach | Mutates original? | Creates new object? | Common use | Notes |
|---|---|---|---|---|
Object.assign(obj1, obj2) | Yes | No | Directly add properties to an existing object | Good when mutation is acceptable |
Object.assign({}, obj1, obj2) | No | Yes | Merge into a fresh object | Clear and widely supported |
{ ...obj1, ...obj2 } | No | Yes | Modern JavaScript merging | Short and readable |
Object.assign() vs spread syntax
Object.assign()is older and explicit
Cheat Sheet
// Mutate obj1 by copying obj2 into it
Object.assign(obj1, obj2);
// Create a new merged object
const merged = Object.assign({}, obj1, obj2);
// Modern syntax for a new merged object
const merged = { ...obj1, ...obj2 };
Rules to remember
- Objects are merged by copying top-level properties
- If keys conflict, the later object wins
Object.assign(target, source)changestarget- Spread syntax usually creates a new object
- Both are shallow merges, not deep merges
Conflict example
const a = { x: 1 };
const b = { x: 2 };
const c = { ...a, ...b };
// c.x is 2
Safe default pattern
const options = { ...defaultOptions, ...userOptions };
Important edge case
Nested objects are not deeply merged:
FAQ
Is there a built-in merge method on JavaScript objects?
No. Plain JavaScript objects do not have a .merge() method. Use Object.assign() or object spread syntax instead.
What is the easiest way to merge two objects in JavaScript?
For modern JavaScript, the most common approach is:
const merged = { ...obj1, ...obj2 };
Does Object.assign() change the original object?
Yes, it changes the target object you pass in as the first argument.
Which value wins if both objects have the same key?
The value from the later object wins.
Is object spread the same as deep merge?
No. It only copies top-level properties.
Should I use Object.assign() or spread syntax?
Use spread syntax for readability in modern code. Use Object.assign() if you specifically want to mutate an existing target or need that style for compatibility.
Can I merge more than two objects?
Yes.
const result = { ...a, ...b, ...c };
or:
Mini Project
Description
Build a small settings merger for a JavaScript app. The app has default settings, and a user can provide their own overrides. You will combine both objects into one final configuration object. This demonstrates one of the most common real-world uses of object merging.
Goal
Create a function that merges default settings with user-provided settings and returns the final result without changing the original defaults.
Requirements
- Create a
defaultSettingsobject with at least three properties. - Create a
userSettingsobject that overrides at least one property and adds one new property. - Write a function that returns a new merged object.
- Do not mutate the original
defaultSettingsobject. - Print the merged result and the original defaults to verify the behavior.
Keep learning
Related questions
Deep Cloning Objects in JavaScript: Methods, Trade-offs, and Best Practices
Learn how to deep clone objects in JavaScript, compare structuredClone, JSON methods, and recursive approaches with examples.
Get Screen, Page, and Browser Window Size in JavaScript
Learn how to get screen size, viewport size, page size, and scroll position in JavaScript across major browsers with clear examples.
How JavaScript Closures Work: A Beginner-Friendly Guide
Learn how JavaScript closures work with simple explanations, examples, common mistakes, and practical use cases for real code.