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:

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.

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:

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:

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 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 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:

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:

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:

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's merge() method to perform a deep merger of objects. This method recursively merges two or more source objects' properties into a target object:

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.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.