实现
const merge = (target, ...extend) => {
const handleMerge = isArray(target) ? mergeArr : mergeObj;
extend.map(item => (target = handleMerge(target, item)));
return target;
};
const mergeArr = (base, extend, key = 'id') => {
if (!isArray(base)) {
return extend;
}
if (!isArray(extend)) {
return base;
}
const sameItems = {};
[...base, ...extend].map(item => {
const idKey = isObject(item) ? item[key] ?? JSON.stringify(item) : item;
if (sameItems[idKey] === undefined) {
sameItems[idKey] = item;
} else {
const oldItem = sameItems[idKey];
if (isObject(oldItem) && isObject(item)) {
sameItems[idKey] = mergeObj(oldItem, item, key);
} else if (isArray(oldItem) && isArray(item)) {
sameItems[idKey] = mergeArr(oldItem, item, key);
} else {
sameItems[idKey] = item;
}
}
});
return Object.keys(sameItems).map(v => sameItems[v]);
};
const mergeObj = (base, extend, key = 'id') => {
if (!isObject(base)) {
return extend;
}
if (!isObject(extend)) {
return base;
}
for (let k in extend) {
if (hasProp(extend, k)) {
if (isObject(base[k]) && isObject(extend[k])) {
base[k] = mergeObj(base[k], extend[k], key);
} else if (isArray(base[k]) && isArray(extend[k])) {
base[k] = mergeArr(base[k], extend[k], key);
} else {
base[k] = extend[k];
}
} else {
Object.setPrototypeOf(base, {[k]: extend[k]});
}
}
return base;
};
使用
merge(target, ...extend);
示例
const a = {
num: 12,
str: 'hello',
nul: null,
arr: [
{
name: 'a1',
children: [1, 'hi'],
},
],
obj: {
name: 'obj',
age: 22,
oa1: [2, null, 'oa1'],
oa2: {
name: 'test',
},
},
};
const b = {
num: 22,
arr: [
{
children: [3],
},
],
obj: {
oa2: {
age: 30,
},
},
obj2: {
data: [1, 2, 3],
},
};
const c = [
{
test: 123,
},
];
merge(a, b, c, {str: 'ihuxy'});


演示地址:ihuxy.com/play?utils=…