$.extend
is not meant to be used this way.
However you can write your own extend/merge function. Here's an example of a function that will merge every objects considered equal (based on the value of a specific key) from multiple provided arrays together.
The following merge algorithm will override primitive values and will concatenate arrays.
The initial arrays and their objects aren't modified.
It's probably overkill if you only have to do this once, however it's an example on how you could implement your own encapsulated merging algorithm.
function mergeOnKey(mergeKey) {
var mergedObjectsIndex = {},
mergedObjects = [],
arrays = Array.prototype.slice.call(arguments, 1),
i = 0,
arraysLen = arrays.length,
x, arrLen, arr, obj, k,
mergeVal, mergedObjIndex,
mergedObj, mergedVal;
for (; i < arraysLen ; i++) {
arr = arrays[i];
for (x = 0, arrLen = arr.length; x < arrLen; x++) {
obj = arr[x];
mergeVal = obj[mergeKey];
mergedObjIndex = mergedObjectsIndex[mergeVal];
if (typeof mergedObjIndex === 'undefined') {
mergedObjectsIndex[mergeVal] = mergedObjects.push($.extend({}, obj)) - 1;
continue;
}
mergedObj = mergedObjects[mergedObjIndex];
for (k in obj) {
if (!obj.hasOwnProperty(k) || k === mergeKey) continue;
if (Array.isArray(mergedVal = mergedObj[k])) mergedObj[k] = mergedVal.concat(obj[k]);
else mergedObj[k] = obj[k];
}
}
}
return mergedObjects;
}
You could then use it like:
var obj1 = [
{ name: 'styles', items: ['Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks'] }
];
var obj2 = [
{ name: 'tools', items: ['Source'], test: 'test' }
];
var merged = mergeOnKey('name', obj1, obj2);
console.log(merged[2].items); //["Maximize", "ShowBlocks", "Source"]