Lodash is trying to be helpful by recursively merging subobjects

This method is like _.assign except that it recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Source properties that resolve to undefined are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.

https://lodash.com/docs/4.17.15#merge (emphasis mine)

If you don't want this to happen, just use the standard ES6 spread operator ... or Object.assign

const object1 = { 
  name: 'John',
  age: 23,
  books: ['book1', 'book2']
};

const object2 = { 
  name: 'John',
  age: 23,
  books: ['book3'],
  city: 'London'
};

object3 = {...object1, ...object2};
object4 = Object.assign({}, object1, object2);

console.log(object3);
console.log(object4);
/* make the Stack Overflow console bigger */ .as-console-wrapper { max-height: 100vh !important; }

Answer from Samathingamajig on Stack Overflow
๐ŸŒ
Lodash
lodash.com โ€บ docs
Lodash Documentation
Many lodash methods are guarded to work as iteratees for methods like _.reduce, _.reduceRight, and _.transform. The guarded methods are: assign, defaults, defaultsDeep, includes, merge, orderBy, and sortBy ยท 0.1.0 ยท collection (Array|Object): The collection to iterate over.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ javascript โ€บ lodash-_-merge-method
Lodash _.merge() Method - GeeksforGeeks
Lodash _.merge() method is used to merge two or more objects, starting from the left-most to the right-most to create a parent mapping object.
Published ย  August 5, 2025
Discussions

Lodash merge including undefined values
I'm trying to use Lodash to merge object A into object B, but the trouble I am having is that object A has some undefined values and I want these to be copied over to object B. Lodash docs for ... More on github.com
๐ŸŒ github.com
3
August 26, 2021
Lodash merge two objects but replace the same key values with new object value
Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources. https://lodash.com/docs/4.17.15#merge (emphasis mine) More on stackoverflow.com
๐ŸŒ stackoverflow.com
Lodash - difference between .extend() / .assign() and .merge()
In the Lodash library, can someone provide a better explanation of merge and extend / assign. Its a simple question but the answer evades me nonetheless. ... Here's how extend/assign works: For each property in source, copy its value as-is to destination. if property values themselves are objects, ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Is there a benefit to using lodash.merge (or other utilities of the same feature) versus merging via object destructuring?
Yes, absolutely. Lodash merge recursively merges properties at every level. If you merged two objects with destructuring (or lodash.assign or Object.assign which are equivalent), it drops anything that is not top-level from the first object. See: https://lodash.com/docs#merge More on reddit.com
๐ŸŒ r/node
13
4
November 14, 2022
๐ŸŒ
Dustin John Pfister
dustinpfister.github.io โ€บ 2017 โ€บ 11 โ€บ 17 โ€บ lodash_merge
_.merge in lodash as a means to recursively merge down objects. | Dustin John Pfister at github pages
November 25, 2021 - When you have a whole bunch of nested objects in an object do you want to just copy the first level into a new object, or do you want to recursively copy everything? In sort a shallow clone of an object is nit the same thing as a deep clone of one. The lodash _.merge differs from lodash _.assign method in that _.assign will create a new object for my deltas overwriting any values that may exist in any lower object.
๐ŸŒ
egghead.io
egghead.io โ€บ lessons โ€บ javascript-deep-merge-objects-in-javascript-with-spread-lodash-and-deepmerge
Deep Merge Objects in JavaScript with Spread, Lodash, and Deepmerge | egghead.io
Back in the file, we can require lodash and then use lodash's merge function, which will handle the deep merge for us. We can say that the merged value is the merge of person and update.
Published ย  January 17, 2019
๐ŸŒ
GitHub
github.com โ€บ lodash โ€บ lodash โ€บ issues โ€บ 5242
Lodash merge including undefined values ยท Issue #5242 ยท lodash/lodash
August 26, 2021 - I'm trying to use Lodash to merge object A into object B, but the trouble I am having is that object A has some undefined values and I want these to be copied over to object B. Lodash docs for _.merge() says: "Recursively merges own enum...
Author ย  liangyuqi
๐ŸŒ
Mastering JS
masteringjs.io โ€บ tutorials โ€บ lodash โ€บ merge
Lodash's `merge()` Function - Mastering JS
Given two objects destination and source, Lodash's merge() function copies the 2nd object's own properties and inherited properties into the first object.
๐ŸŒ
The Syntax Diaries
thesyntaxdiaries.com โ€บ lodash-merge-a-comprehensive-guide
Lodash _.merge() Deep Merge Objects & Arrays โ€” Guide with Examples
February 9, 2026 - Lodash _.merge() is a JavaScript utility method that recursively deep merges properties of source objects into a destination object.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ lodash โ€บ lodash_merge.htm
Lodash - merge method
Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources. object ...
Find elsewhere
๐ŸŒ
Marius Schulz
mariusschulz.com โ€บ blog โ€บ combining-settings-objects-with-lodash-assign-or-merge
Combining Settings Objects with Lodash: _.assign or _.merge? โ€” Marius Schulz
November 1, 2020 - The lodash library contains two similar functions, _.assign and _.merge, that assign property values of some source object(s) to a target object, effectively merging their properties.
Top answer
1 of 5
633

Here's how extend/assign works: For each property in source, copy its value as-is to destination. if property values themselves are objects, there is no recursive traversal of their properties. Entire object would be taken from source and set in to destination.

Here's how merge works: For each property in source, check if that property is object itself. If it is then go down recursively and try to map child object properties from source to destination. So essentially we merge object hierarchy from source to destination. While for extend/assign, it's simple one level copy of properties from source to destination.

Here's simple JSBin that would make this crystal clear: http://jsbin.com/uXaqIMa/2/edit?js,console

Here's more elaborate version that includes array in the example as well: http://jsbin.com/uXaqIMa/1/edit?js,console

2 of 5
616

Lodash version 3.10.1

Methods compared

  • _.merge(object, [sources], [customizer], [thisArg])
  • _.assign(object, [sources], [customizer], [thisArg])
  • _.extend(object, [sources], [customizer], [thisArg])
  • _.defaults(object, [sources])
  • _.defaultsDeep(object, [sources])

Similarities

  • None of them work on arrays as you might expect
  • _.extend is an alias for _.assign, so they are identical
  • All of them seem to modify the target object (first argument)
  • All of them handle null the same

Differences

  • _.defaults and _.defaultsDeep processes the arguments in reverse order compared to the others (though the first argument is still the target object)
  • _.merge and _.defaultsDeep will merge child objects and the others will overwrite at the root level
  • Only _.assign and _.extend will overwrite a value with undefined

Tests

They all handle members at the root in similar ways.

_.assign      ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.merge       ({}, { a: 'a' }, { a: 'bb' }) // => { a: "bb" }
_.defaults    ({}, { a: 'a' }, { a: 'bb' }) // => { a: "a"  }
_.defaultsDeep({}, { a: 'a' }, { a: 'bb' }) // => { a: "a"  }

_.assign handles undefined but the others will skip it

_.assign      ({}, { a: 'a'  }, { a: undefined }) // => { a: undefined }
_.merge       ({}, { a: 'a'  }, { a: undefined }) // => { a: "a" }
_.defaults    ({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }
_.defaultsDeep({}, { a: undefined }, { a: 'bb' }) // => { a: "bb" }

They all handle null the same

_.assign      ({}, { a: 'a'  }, { a: null }) // => { a: null }
_.merge       ({}, { a: 'a'  }, { a: null }) // => { a: null }
_.defaults    ({}, { a: null }, { a: 'bb' }) // => { a: null }
_.defaultsDeep({}, { a: null }, { a: 'bb' }) // => { a: null }

But only _.merge and _.defaultsDeep will merge child objects

_.assign      ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "b": "bb" }}
_.merge       ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}
_.defaults    ({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a" }}
_.defaultsDeep({}, {a:{a:'a'}}, {a:{b:'bb'}}) // => { "a": { "a": "a", "b": "bb" }}

And none of them will merge arrays it seems

_.assign      ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.merge       ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "bb" ] }
_.defaults    ({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a"  ] }
_.defaultsDeep({}, {a:['a']}, {a:['bb']}) // => { "a": [ "a"  ] }

All modify the target object

a={a:'a'}; _.assign      (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.merge       (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaults    (a, {b:'bb'}); // a => { a: "a", b: "bb" }
a={a:'a'}; _.defaultsDeep(a, {b:'bb'}); // a => { a: "a", b: "bb" }

None really work as expected on arrays

Note: As @Mistic pointed out, Lodash treats arrays as objects where the keys are the index into the array.

_.assign      ([], ['a'], ['bb']) // => [ "bb" ]
_.merge       ([], ['a'], ['bb']) // => [ "bb" ]
_.defaults    ([], ['a'], ['bb']) // => [ "a"  ]
_.defaultsDeep([], ['a'], ['bb']) // => [ "a"  ]

_.assign      ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.merge       ([], ['a','b'], ['bb']) // => [ "bb", "b" ]
_.defaults    ([], ['a','b'], ['bb']) // => [ "a", "b"  ]
_.defaultsDeep([], ['a','b'], ['bb']) // => [ "a", "b"  ]
Top answer
1 of 2
65

If both arrays are in the correct order; where each item corresponds to its associated member identifier then you can simply use.

var merge = _.merge(arr1, arr2);

Which is the short version of:

var merge = _.chain(arr1).zip(arr2).map(function(item) {
    return _.merge.apply(null, item);
}).value();

Or, if the data in the arrays is not in any particular order, you can look up the associated item by the member value.

var merge = _.map(arr1, function(item) {
    return _.merge(item, _.find(arr2, { 'member' : item.member }));
});

You can easily convert this to a mixin. See the example below:

_.mixin({
  'mergeByKey' : function(arr1, arr2, key) {
    var criteria = {};
    criteria[key] = null;
    return _.map(arr1, function(item) {
      criteria[key] = item[key];
      return _.merge(item, _.find(arr2, criteria));
    });
  }
});

var arr1 = [{
  "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")',
  "bank": 'ObjectId("575b052ca6f66a5732749ecc")',
  "country": 'ObjectId("575b0523a6f66a5732749ecb")'
}, {
  "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")',
  "bank": 'ObjectId("575b052ca6f66a5732749ecc")',
  "country": 'ObjectId("575b0523a6f66a5732749ecb")'
}];

var arr2 = [{
  "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")',
  "name": 'yyyyyyyyyy',
  "age": 26
}, {
  "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")',
  "name": 'xxxxxx',
  "age": 25
}];

var arr3 = _.mergeByKey(arr1, arr2, 'member');

document.body.innerHTML = JSON.stringify(arr3, null, 4);
body { font-family: monospace; white-space: pre; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

2 of 2
58

Create dictionaries for both arrays using _.keyBy(), merge the dictionaries, and convert the result to an array with _.values(). In this way, the order of the arrays doesn't matter. In addition, it can also handle arrays of different length.

const ObjectId = (id) => id; // mock of ObjectId
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}];
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}];

const merged = _(arr1) // start sequence
  .keyBy('member') // create a dictionary of the 1st array
  .merge(_.keyBy(arr2, 'member')) // create a dictionary of the 2nd array, and merge it to the 1st
  .values() // turn the combined dictionary to array
  .value(); // get the value (array) out of the sequence

console.log(merged);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

Using ES6 Map

Concat the arrays, and reduce the combined array to a Map. Use Object#assign to combine objects with the same member to a new object, and store in map. Convert the map to an array with Map#values and spread:

const ObjectId = (id) => id; // mock of ObjectId
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}];
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}];

const merged = [...arr1.concat(arr2).reduce((m, o) => 
  m.set(o.member, Object.assign(m.get(o.member) || {}, o))
, new Map()).values()];

console.log(merged);

๐ŸŒ
Lodash
lodash.info โ€บ doc โ€บ merge
merge - Lodash documentation
var object = { 'a': [{ 'b': 2 }, { 'd': 4 }] }; var other = { 'a': [{ 'c': 3 }, { 'e': 5 }] }; _.merge(object, other); // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
๐ŸŒ
npm
npmjs.com โ€บ package โ€บ lodash.merge
lodash.merge - npm
The Lodash method `_.merge` exported as a module.. Latest version: 4.6.2, last published: 7 years ago. Start using lodash.merge in your project by running `npm i lodash.merge`. There are 7028 other projects in the npm registry using lodash.merge.
      ยป npm install lodash.merge
    
Published ย  Jul 10, 2019
Version ย  4.6.2
Author ย  John-David Dalton
Homepage ย  https://lodash.com/
๐ŸŒ
egghead.io
egghead.io โ€บ lessons โ€บ javascript-build-lodash-merge-from-scratch
Build lodash.merge from Scratch | egghead.io
May 26, 2020 - After getting basic types to merge we'll show off two methods for merging arrays, either using concat or recursively going through the children and merging them. Finally we'll build our own isObject function to check for object literals and recursively apply our mergeJSON function to any object literals in our source object.
๐ŸŒ
StudyRaid
app.studyraid.com โ€บ en โ€บ read โ€บ 11765 โ€บ 373056 โ€บ merging-objects-with-merge
Merging objects with _.merge - Master JavaScript Utility ...
_.merge in Lodash performs a deep merge of objects, combining properties recursively. It prioritizes the rightmost source object for overlapping keys.
๐ŸŒ
Docs-lodash
docs-lodash.com โ€บ v4 โ€บ merge
_.merge โ€“ Lodash Docs v4.17.11
var object = { 'a': [{ 'b': 2 }, { 'd': 4 }] }; var other = { 'a': [{ 'c': 3 }, { 'e': 5 }] }; _.merge(object, other); // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }