# How to merge two objects in JavaScript

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Jun 14, 2020, updated Aug 26, 2022. Topics: JavaScript.
Canonical URL: https://attacomsian.com/blog/javascript-merge-objects

> A detailed article to learn about different ways to combine properties of two objects into a new object in JavaScript.

There are multiple ways to merge two objects in JavaScript. 

1. Use the  `Object.assign()` method or spread operator (`...`) to perform a shallow merge of two objects. 
2. For a deeper merge, write a custom function or use a 3rd-party library like Lodash.

## `Object.assign()` Method

The `Object.assign(target, source1, soure2, ...)` method was introduced in ES6. It copies all enumerable own properties of one or more source objects to a target object and returns the target object.

The following example uses `Object.assign()` to merge the `profile` and `job` objects into the `user` object:

```javascript
const profile = {
  name: 'John Doe',
  age: 25
}

const job = {
  profession: 'IT Engineer'
}

const user = Object.assign(profile, job)

console.log(user)
// { name: 'John Doe', age: 25, profession: 'IT Engineer' }
```

There is no limit to the number of objects you can merge with `Object.assign()`. 

All source objects get merged into the first object. Only the target object is mutated and returned.

```javascript
const obj1 = { a: 1 }
const obj2 = { b: 2 }
const obj3 = { c: 3 }

const obj = Object.assign(obj1, obj2, obj3)

console.log(obj)
// { a: 1, b: 2, c: 3 }
```

If you don't want to mutate the target object, just pass an empty object `{}` as a target:

```javascript
const obj = Object.assign({}, obj1, obj2, obj3)

console.log(obj)
// { a: 1, b: 2, c: 3 }
```

The properties are overwritten by other objects that have the same properties later in the order of the parameters:

```javascript
const obj1 = { a: 1, b: 1, c: 1 }
const obj2 = { b: 2, c: 2 }
const obj3 = { c: 3 }

const obj = Object.assign({}, obj1, obj2, obj3)

console.log(obj)
// { a: 1, b: 2, c: 3 }
```

Read [this guide](https://attacomsian.com/blog/javascript-object-assign) to learn more about the `Object.assign()` method.

## Spread Operator

ES6 introduced the spread operator (`...`) that can also be used to merge two or more objects to [create a new one](https://attacomsian.com/blog/javascript-create-object) that has properties of the merged objects.

> **Note:** Spread operators were first introduced in ES6 (ECMAScript 2015) but object literal spread support was added in ES9 (ECMAScript 2018).

Here is an example that uses object spread syntax to merge two objects:

```javascript
const profile = {
  name: 'John Doe',
  age: 25
}

const job = {
  profession: 'IT Engineer'
}

const user = { ...profile, ...job }

console.log(user)
// { name: 'John Doe', age: 25, profession: 'IT Engineer' }
```

The object spread is a relatively new feature and only works in the latest versions of modern browsers. Similar to `Object.assign()`, it allows you to merge any number of objects with the identical handling of duplicate keys.

## Custom Function

You can also write your own custom function to merge two or more objects:

```javascript
const merge = (...arguments) => {
  // create a new object
  let target = {}

  // merge the object into the target object
  const merger = obj => {
    for (let prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        target[prop] = obj[prop]
      }
    }
  }

  // iterate through all objects and merge them with target
  for (let i = 0; i < arguments.length; i++) {
    merger(arguments[i])
  }

  return target
}

const profile = {
  name: 'John Doe',
  age: 25
}

const job = {
  profession: 'IT Engineer'
}

const user = merge(profile, job)

console.log(user)
// { name: 'John Doe', age: 25, profession: 'IT Engineer' }
```

## Deep Merge Objects

To deep merge two or more objects, you need to recursively copy all objects' own properties, nested arrays, functions, and extended properties to the target object.

Let us extend the above function to perform a deep merger of multiple objects:

```javascript
const merge = (...arguments) => {
  // create a new object
  let target = {}

  // deep merge the object into the target object
  const merger = obj => {
    for (let prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        if (Object.prototype.toString.call(obj[prop]) === '[object Object]') {
          // if the property is a nested object
          target[prop] = merge(target[prop], obj[prop])
        } else {
          // for regular property
          target[prop] = obj[prop]
        }
      }
    }
  }

  // iterate through all objects and
  // deep merge them with target
  for (let i = 0; i < arguments.length; i++) {
    merger(arguments[i])
  }

  return target
}

const profile = {
  name: 'John Doe',
  age: 25,
  address: {
    city: 'Berlin',
    country: 'DE'
  }
}

const job = {
  profession: 'IT Engineer',
  skills: ['JavaScript', 'React', 'Node']
}

// perform deep merge
const user = merge(profile, job)

console.log(user)

// {
//     name: 'John Doe',
//     age: 25,
//     address: { city: 'Berlin', country: 'DE' },
//     profession: 'IT Engineer',
//     skills: ['JavaScript', 'React', 'Node']
// }
```

## Lodash `merge()` Method

You can also use [Lodash](https://lodash.com/docs/4.17.15#merge)'s `merge()` method to perform a deep merger of objects. This method recursively merges two or more source objects' properties into a target object:

```javascript
const _ = require('lodash')

const profile = {
  name: 'John Doe',
  age: 25,
  address: {
    city: 'Berlin',
    country: 'DE'
  }
}

const job = {
  profession: 'IT Engineer',
  skills: ['JavaScript', 'React', 'Node']
}

// deep merge objects
const user = _.merge(profile, job)

console.log(user)

// {
//     name: 'John Doe',
//     age: 25,
//     address: { city: 'Berlin', country: 'DE' },
//     profession: 'IT Engineer',
//     skills: ['JavaScript', 'React', 'Node']
// }
```

To learn more about JavaScript objects, prototypes, and classes, read [this guide](https://attacomsian.com/blog/objects-prototypes-classes-javascript).
