Recursive/deep extend/assign in Underscore.js?
With Lodash (fork of underscore) you can. Lodash's _.extend method accept third (or higher) parameter to be a function, that receives values (old and new); So you can do something like this:
var deep = function(a, b) {
return _.isObject(a) && _.isObject(b) ? _.extend(a, b, deep) : b;
};
var a = {a:{b:{c:1}}},
b = {a:{b:{z:1}}};
_.extend(a,b,deep);
upd. As Paolo Moretti said in comments, there is the same function in lodash called _.merge:
_.merge(a,b);
jQuery has an extend() function, which does the same thing as its Underscore counterpart, but also has a deep argument which allows it to merge recursively as you desire:
var creditOperation = $.extend(true, baseOperation, {
query: {
'method': 'baz'
}
});
Or, if you don't want to overwrite baseOperation:
var creditOperation = $.extend(true, {}, baseOperation, {
query: {
'method': 'baz'
}
});
Underscore has no plans to add a deep extend since it's deemed too complicated to deal with different types of objects. Instead, users are encouraged to implement their own solutions with the support for what they need.
In your case it's only plain objects, so an implementation is quite straightforward:
_.deepObjectExtend = function(target, source) {
for (var prop in source)
if (prop in target)
_.deepObjectExtend(target[prop], source[prop]);
else
target[prop] = source[prop];
return target;
}