Это должно делать то, что вы ищете. Он будет рекурсивно объединять произвольно глубокие объекты в массивы.
// 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;
}
И этот будет делать то же самое, за исключением того, что объединенный объект будет содержать копии унаследованных свойств. Это, вероятно, не то, что вы ищете (согласно комментариям RobG ниже), но если это действительно то, что вы ищете, то вот оно:
// 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;
}
Я попробовал это на вашем примере на http://jsconsole.com,, и он работал нормально:
deepmerge(foo, bar)
{"a": [1, 3], "b": [2, 4]}
bar
{"a": 3, "b": 4}
foo
{"a": 1, "b": 2}
Работали также несколько более сложные объекты:
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;}}}