This ought to do what you're looking for. It will recursively merge arbitrarily deep objects into arrays.

// deepmerge by Zachary Murray (dremelofdeath) CC-BY-SA 3.0
function deepmerge(foo, bar) {
  var merged = {};
  for (var each in bar) {
    if (foo.hasOwnProperty(each) && bar.hasOwnProperty(each)) {
      if (typeof(foo[each]) == "object" && typeof(bar[each]) == "object") {
        merged[each] = deepmerge(foo[each], bar[each]);
      } else {
        merged[each] = [foo[each], bar[each]];
      }
    } else if(bar.hasOwnProperty(each)) {
      merged[each] = bar[each];
    }
  }
  for (var each in foo) {
    if (!(each in bar) && foo.hasOwnProperty(each)) {
      merged[each] = foo[each];
    }
  }
  return merged;
}

And this one will do the same, except that the merged object will include copies of inherited properties. This probably isn't what you're looking for (as per RobG's comments below), but if that is actually what you are looking for, then here it is:

// deepmerge_inh by Zachary Murray (dremelofdeath) CC-BY-SA 3.0
function deepmerge_inh(foo, bar) {
  var merged = {};
  for (var each in bar) {
    if (each in foo) {
      if (typeof(foo[each]) == "object" && typeof(bar[each]) == "object") {
        merged[each] = deepmerge(foo[each], bar[each]);
      } else {
        merged[each] = [foo[each], bar[each]];
      }
    } else {
      merged[each] = bar[each];
    }
  }
  for (var each in foo) {
    if (!(each in bar)) {
      merged[each] = foo[each];
    }
  }
  return merged;
}

I tried it out with your example on http://jsconsole.com, and it worked fine:

deepmerge(foo, bar)
{"a": [1, 3], "b": [2, 4]}
bar
{"a": 3, "b": 4}
foo
{"a": 1, "b": 2}

Slightly more complicated objects worked as well:

deepmerge(as, po)
{"a": ["asdf", "poui"], "b": 4, "c": {"q": [1, 444], "w": [function () {return 5;}, function () {return 1123;}]}, "o": {"b": {"t": "cats"}, "q": 7}, "p": 764}
po
{"a": "poui", "c": {"q": 444, "w": function () {return 1123;}}, "o": {"b": {"t": "cats"}, "q": 7}, "p": 764}
as
{"a": "asdf", "b": 4, "c": {"q": 1, "w": function () {return 5;}}}
Answer from Zachary Murray on Stack Overflow
๐ŸŒ
Better Programming
betterprogramming.pub โ€บ combining-javascript-objects-e293bc4a48a6
3 Ways To Combine JavaScript Objects | by Corey Butler | Better Programming
March 5, 2021 - The result of this is exactly the same as the result of Object.assign(). The major difference between the two approaches is control over how the merging occurs (lines 16-18). ... This approach can be effective whenever greater control of the merging process is necessary. Aside from preventing conflicting names from overwriting each other, there are many other data modifications that can be made.
๐ŸŒ
Atomizedobjects
atomizedobjects.com โ€บ blog โ€บ javascript โ€บ how-to-merge-two-objects-in-javascript
How to merge two objects in JavaScript | Atomized Objects
As you can see from this example we create a new property with precedence after merging the original two objects in, and then we use the spread syntax once again within the new version of the property for both objects with that property to extract all the keys without overwriting and losing the information. There we have how to merge two objects in JavaScript, if you want more like this be sure to check out some of my other posts!
Discussions

javascript - Merge JS objects without overwriting - Stack Overflow
I would expect a function that ... not a mix of strings, objects, functions and so on. It also doesn't fitler out inhertied properties, nor deal with functions that have own properties. 2011-09-26T02:11:08.093Z+00:00 ... If you were merging two objects of completely different ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
How can I merge properties of two JavaScript objects? - Stack Overflow
ES2018/TypeScript: Many answers ... to merge two objects without overwriting overlapping object keys. My function also accepts unlimited number of objects to merge as function arguments: (I'm using TypeScript notation here, feel free to delete the :object[] type in the function argument if you're using plain JavaScript)... More on stackoverflow.com
๐ŸŒ stackoverflow.com
How do you merge two objects with the same properties without overriding them?
You can't get it done unless you change the name of the conflicting properties. Duplicate keys cannot exist in an object. More on reddit.com
๐ŸŒ r/learnprogramming
16
3
November 17, 2021
Merge two javascript objects without overwriting - Stack Overflow
However, this results in the data from the second object to overwrite the data of the first object. More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
30 Seconds of Code
30secondsofcode.org โ€บ home โ€บ javascript โ€บ object โ€บ merge objects
Merge two or more JavaScript objects - 30 seconds of code
March 20, 2024 - const obj1 = { a: 1, b: 2 }; const obj2 = { b: 3, c: 4 }; const merged = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 } const merged2 = Object.assign({}, obj2, obj1); // { b: 2, c: 4, a: 1 } Instead of overwriting properties with the same key, we usually want to combine their values.
Top answer
1 of 4
10

This ought to do what you're looking for. It will recursively merge arbitrarily deep objects into arrays.

// deepmerge by Zachary Murray (dremelofdeath) CC-BY-SA 3.0
function deepmerge(foo, bar) {
  var merged = {};
  for (var each in bar) {
    if (foo.hasOwnProperty(each) && bar.hasOwnProperty(each)) {
      if (typeof(foo[each]) == "object" && typeof(bar[each]) == "object") {
        merged[each] = deepmerge(foo[each], bar[each]);
      } else {
        merged[each] = [foo[each], bar[each]];
      }
    } else if(bar.hasOwnProperty(each)) {
      merged[each] = bar[each];
    }
  }
  for (var each in foo) {
    if (!(each in bar) && foo.hasOwnProperty(each)) {
      merged[each] = foo[each];
    }
  }
  return merged;
}

And this one will do the same, except that the merged object will include copies of inherited properties. This probably isn't what you're looking for (as per RobG's comments below), but if that is actually what you are looking for, then here it is:

// deepmerge_inh by Zachary Murray (dremelofdeath) CC-BY-SA 3.0
function deepmerge_inh(foo, bar) {
  var merged = {};
  for (var each in bar) {
    if (each in foo) {
      if (typeof(foo[each]) == "object" && typeof(bar[each]) == "object") {
        merged[each] = deepmerge(foo[each], bar[each]);
      } else {
        merged[each] = [foo[each], bar[each]];
      }
    } else {
      merged[each] = bar[each];
    }
  }
  for (var each in foo) {
    if (!(each in bar)) {
      merged[each] = foo[each];
    }
  }
  return merged;
}

I tried it out with your example on http://jsconsole.com, and it worked fine:

deepmerge(foo, bar)
{"a": [1, 3], "b": [2, 4]}
bar
{"a": 3, "b": 4}
foo
{"a": 1, "b": 2}

Slightly more complicated objects worked as well:

deepmerge(as, po)
{"a": ["asdf", "poui"], "b": 4, "c": {"q": [1, 444], "w": [function () {return 5;}, function () {return 1123;}]}, "o": {"b": {"t": "cats"}, "q": 7}, "p": 764}
po
{"a": "poui", "c": {"q": 444, "w": function () {return 1123;}}, "o": {"b": {"t": "cats"}, "q": 7}, "p": 764}
as
{"a": "asdf", "b": 4, "c": {"q": 1, "w": function () {return 5;}}}
2 of 4
3

Presumably you would iterate over one object and copy its property names to a new object and values to arrays assigned to those properties. Iterate over subsequent objects, adding properties and arrays if they don't already exist or adding their values to existing properties and arrays.

e.g.

function mergeObjects(a, b, c) {
  c = c || {};
  var p;

  for (p in a) {
    if (a.hasOwnProperty(p)) {
      if (c.hasOwnProperty(p)) {
        c[p].push(a[p]);
      } else {
        c[p] = [a[p]];
      }
    }
  }
  for (p in b) {
    if (b.hasOwnProperty(p)) {
      if (c.hasOwnProperty(p)) {
        c[p].push(b[p]);
      } else {
        c[p] = [b[p]];
      }
    }
  }
  return c;
}

You could modify it to handle any number of objects by iterating over the arguments supplied, but that would make passing the object to merge into more difficult.

๐ŸŒ
CoreUI
coreui.io โ€บ blog โ€บ how-to-merge-objects-in-javascript
How to Merge Objects in JavaScript ยท CoreUI
February 27, 2024 - Shallow merging is straightforward in JavaScript, thanks to modern ES6 features like the spread operator (...) and the Object.assign() method. Introduced in ES6, the spread operator (...) has become a go-to for many developers due to its concise ...
๐ŸŒ
Reddit
reddit.com โ€บ r/learnprogramming โ€บ how do you merge two objects with the same properties without overriding them?
r/learnprogramming on Reddit: How do you merge two objects with the same properties without overriding them?
November 17, 2021 -

Hi, I would greatly appreciate your help if anyone of you have the time to help me solve this problem.

I'm trying to merge these two objects:

const userx = {
name: 'Alex',
address: '15th Park Avenue',
age: 43,
};
const department = {
id: '001',
Shift: 'Morning',
name: 'Sales',
};

// solutions tried:

1st -
const completeDetails = { ...userx, ...department }; // Shift: "Morning", address: "15th Park Avenue", age: 43id: "001", name: "Sales"

2nd -
const completeDetails = JSON.parse(JSON.stringify({ ...userx, ...department })); Shift: "Morning", address: "15th Park Avenue", age: 43id: "001", name: "Sales"

I tried deep cloning but as you can see it still overrides the name property. I would like the output to be:
name: 'Alex',
address: "15th Park Avenue",
age: 43,
id: "001",
Shift: "Morning",
name: "Sales"

Find elsewhere
Top answer
1 of 6
17

For those who don't use jQuery, here comes a vanilla-js solution.

Solution:

function extend (target) {
    for(var i=1; i<arguments.length; ++i) {
        var from = arguments[i];
        if(typeof from !== 'object') continue;
        for(var j in from) {
            if(from.hasOwnProperty(j)) {
                target[j] = typeof from[j]==='object'
                ? extend({}, target[j], from[j])
                : from[j];
            }
        }
    }
    return target;
}

Compressed (with Closure Compiler):

Only 199 characters!

var extend=function e(c){for(var d=1;d<arguments.length;++d){var a=arguments[d];if("object"===typeof a)for(var b in a)a.hasOwnProperty(b)&&(c[b]="object"===typeof a[b]?e({},c[b],a[b]):a[b])}return c}

How to use:

extend(target, obj1, obj2); // returns target

If you only want to merge, use

var merged = extend({}, obj1, obj2);

Features:

  • It doesn't look at objects' prototype.
  • Ignores non-objects.
  • It is recursive in order to merge properties which are objects.
  • Objects referenced in target's properties, if extended, are replaced by new ones, and the original ones are not modified.
  • In case of same property names, the merged value will be the merging of the objects after the last (in the order of arguments) non-object value. Or, if the last isn't an object, itself.

Examples:

extend({}, {a:1}, {a:2});            // {a:2}
extend({}, {a:1}, {b:2});            // {a:1, b:2}
extend({}, {a: {b:1}}, {a: {b:2}});  // {a: {b:2}}
extend({}, {a: {b:1}}, {a: {c:2}});  // {a: {b:2, c:2}}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'});
    // {a: "whatever non object"}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'}, {a: {c:3}},{a: {d:4}});
    // {a: {c:3, d:4}}

Warning:

Be aware that if browser is not clever enough, it could be trapped in an infinite loop:

var obj1={},
    obj2={};
obj1.me=obj1;
obj2.me=obj2;
extend({},obj1,obj2);

If the browser is clever enough, it can throw an error, or return {me: undefined}, or whatever.

Note that this warning also applies if you use jQuery's $.extend.

2 of 6
12

With ES2015 now being supported in all modern browsers, the native Object.assign can be used to extend objects

Object.assign({}, _default, values)

Object.assign

Note that default is a reserved keyword, and can't be used as a variable name


The original answer, written in 2013 :

Since this is tagged with jQuery, you could use $.extend for a simple cross-browser solution

var temp = {};
$.extend(true, temp, _default, values);
values = temp;

๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 64579168 โ€บ merge-two-objects-without-overwriting-same-properties โ€บ 64579823
javascript - Merge two objects without overwriting same properties - Stack Overflow
October 29, 2020 - If the objective is to merge your two objects without affecting the keys already in the first object, you could create your own utilitary function like this.
๐ŸŒ
Stack Abuse
stackabuse.com โ€บ merge-properties-of-two-objects-dynamically-in-javascript
Merge Properties of Two Objects Dynamically in JavaScript
October 4, 2023 - In this tutorial, we've taken a look at how to merge two objects in JavaScript. We've explored the spread operator (...) and the Object.assign() method, which both perform a shallow merge of two or more objects, into a new one, without affecting the constituent parts.
๐ŸŒ
Scaler
scaler.com โ€บ home โ€บ topics โ€บ javascript merge objects
JavaScript Merge Objects - Scaler Topics
May 4, 2023 - Shallow merge is a way of merging in Javascript. It basically merges two JS objects, but there is a catch here, if we have a key or keys in both the objects with the same name, then doing a shallow merge will replace the value of the former object with the latter.
๐ŸŒ
SitePoint
sitepoint.com โ€บ blog โ€บ javascript โ€บ how to merge objects in javascript
How to Merge Objects in JavaScript โ€” SitePoint
November 5, 2024 - Learn how to merge any object in JavaScript with the spread ( ... ) operator, Object.assign() method, and JSON stringify and parse methods.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ article โ€บ how-to-add-properties-from-one-object-into-another-without-overwriting-in-javascript
How to add properties from one object into another without overwriting in JavaScript?
March 15, 2026 - const first = {key1: 100, key2: ... 40, key3: 70, key4: 1000, key1: 100 } Use the spread operator for modern JavaScript applications, or hasOwnProperty() for older environments....
Top answer
1 of 3
1
const obj1 = { a: 10, b: 13 }
const obj2 = { a: 84, c: 70, d: 40 }

function foo(obj1, obj2) {

    const newObject = {}
    for (const key in { ...obj1, ...obj2 }) {
        const element1 = obj1[key];
        const element2 = obj2[key];
        if (element1 && element2)
            newObject[key] = [element1, element2]
        else if (element1)
            newObject[key] = element1
        else if (element2)
            newObject[key] = element2
    }
    return newObject
}
console.log(foo(obj1, obj2))
2 of 3
0

Here is two solutions, The first one, merge the values of the keys into an object under the same key name. The second one, propose a way to merge them as you mention, but it is a bit more complicated to maintain the index of each key but it is still possible.

The result of both options looks like that

// Option 1
{ a: [ 10, 11, 84 ], b: [ 13, 12 ], c: 70, d: 50 }

// Option 2
{
  a: { '0': 10, '1': 11, '2': 84 },
  b: { '0': 13, '1': 12 },
  c: 70,
  d: 50
}

And here is how it is achieved

const obj1 = { a: { 0: 10, 1: 11 }, b: 13 }
const obj2 = { a: 84, b: 12, c: 70, d: 50 }
const allKeys = Object.keys({ ...obj1, ...obj2 });

const merged1 = {};
for (const key of allKeys) {
    const isObj1Object = typeof obj1[key] === 'object';
    const isObj2Object = typeof obj2[key] === 'object';
    if (obj1[key] && obj2[key]) {
        merged1[key] = [
            ...(isObj1Object ? Object.values(obj1[key]) : [obj1[key]]),
            ...(isObj2Object ? Object.values(obj2[key]) : [obj2[key]]),
        ];
    } else if (obj1[key] || obj2[key]) {
        merged1[key] = obj1[key] || obj2[key];
    }
}

console.log(merged1);

const merged2 = {};
for (const key of allKeys) {
    if (obj1[key] && obj2[key]) {
        const isObj1Object = typeof obj1[key] === 'object';
        const isObj2Object = typeof obj2[key] === 'object';
        merged2[key] = {
            ...(
                isObj1Object
                    ? Object.values(obj1[key]).reduce((acc, v, i) => {
                        acc[Object.keys(obj2[key]).length + i] = v;
                        return acc;
                    }, {})
                    : (
                        isObj2Object
                            ? { [Object.keys(obj2[key]).length]: obj1[key] }
                            : { 0: obj1[key] }
                    )
            ),
            ...(
                isObj2Object
                    ? Object.values(obj2[key]).reduce((acc, v, i) => {
                        acc[Object.keys(obj1[key]).length + i] = v;
                        return acc;
                    }, {})
                    : (
                        isObj1Object
                            ? { [Object.keys(obj1[key]).length]: obj2[key] }
                            : { 1: obj2[key] })
            ),
        };
    } else if (obj1[key] || obj2[key]) {
        merged2[key] = obj1[key] || obj2[key];
    }
}

console.log(merged2);

You can test the different options here playground

If you would like to have a deep merged without any level limitation you would have to update the code to use a recursive method.

๐ŸŒ
Attacomsian
attacomsian.com โ€บ blog โ€บ javascript-merge-objects
How to merge two objects in JavaScript
August 26, 2022 - The properties are overwritten ... console.log(obj) // { a: 1, b: 2, c: 3 } Read this guide to learn more about the Object.assign() method....
๐ŸŒ
Mastering JS
masteringjs.io โ€บ tutorials โ€บ fundamentals โ€บ merge-two-objects
How to Merge Two Objects in JavaScript - Mastering JS
const target = {a: 1, b: 2, c: 3}; const source = {d: 4, e: 5, f: 6}; Object.assign(target, source); target; // {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}
๐ŸŒ
Go Make Things
gomakethings.com โ€บ how-to-deep-merge-arrays-and-objects-with-javascript
How to deep merge arrays and objects with JavaScript | Go Make Things
April 27, 2023 - For each item, weโ€™ll create a copy of the value using the structuredClone() method, and assign that value to the matching key in the clone object. /** * Deep merge two objects * @return {Object} */ function mergeObj (clone, obj) { for (let [key, value] of Object.entries(obj)) { clone[key] = structuredClone(value); } }
๐ŸŒ
YouTube
youtube.com โ€บ watch
How to Merge Objects in JavaScript - 3 Ways! - YouTube
In this video, you will learn how to merge objects in JavaScript using 3 different methods! We'll be using Object.assign(), the spread operator as well as th...
Published: August 9, 2023