深度合并对象的方法
找了很久,现有的库有两个:
1. Merge
npm地址: Merge
用法:
import merge from 'merge';
const obj1 = { name: 2};
const obj2 = { value: 1 };
//合并
merge(obj1,obj2);
console.log(obj1); //{name:2,value:1}
//克隆合并-与目标对象无关联
const obj3 = merge(true,obj1,obj2);
console.log(obj3); //{name:2,value:1}
console.log(obj3 === obj1); //false
//上面两种合并都是类似Object.assgin,只会处理第一层属性,如果需要合并每一个对象的键值,需要使用 recursive方法
//递归合并
const obj4 = {
level: { str: 'hello world' }
};
const obj5 = {
level: { value: 1 },
};
const obj6 = merge.recursive(true,obj4,obj5);
console.log(obj6);
//{level: { str: 'hello world',value: 1 }}
Merge对于对象合并很美好,但是如果对象中存在数组,那么效果就不太行了。
import merge from 'merge';
const obj1 = { arr: [1,2] };
const obj2 = { arr: [3,4] };
merge(obj1,obj2);
console.log(obj1); //{ arr: [3,4] }
看使用场景使用。
2. deepmerge
npm地址: deepmerge
深度合并相比较Merge,它对数组合并做了处理,支持:concat
连接数组,也可以进行替换操作。
替换
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
merge(
[1, 2, 3],
[3, 2, 1],
{ arrayMerge: overwriteMerge }
) // => [3, 2, 1]
连接
merge(
[1, 2],
[3, ],
) // => [1,2,3]
具体我也没怎么用,自行尝试。
3. MuMerge
这个就是我写的,支持对象与对象合并,数组与数组合并,两种合并方式:merge
、cloneMerge
merge是将数据合并到目标对象target参数
,cloneMerge则是合并生成的是一个全新的对象。
代码:
/*
* @Author: mulingyuer
* @Date: 2021-10-13 17:58:00
* @LastEditTime: 2021-10-14 10:18:40
* @LastEditors: mulingyuer
* @Description:合并对象
* @FilePath: \saas-admin-vue\src\base\utils\mu-merge.js
* 怎么可能会有bug!!!
*/
const MuMerge = {
//合并
merge(target, ...source) {
if (MuMerge.isObject(target)) {
return MuMerge.objectMerge(target, ...source);
} else if (MuMerge.isArray(target)) {
return MuMerge.arrayMerge(target, ...source);
} else {
throw new Error("合并target的目标参数不是一个键值对象或者数组");
}
},
//克隆合并-与目标对象无关联
cloneMerge(target, ...source) {
if (MuMerge.isObject(target)) {
return MuMerge.objectMerge({}, target, ...source);
} else if (MuMerge.isArray(target)) {
return MuMerge.arrayMerge([], target, ...source);
} else {
throw new Error("合并target的目标参数不是一个键值对象或者数组");
}
},
//对象合并
objectMerge(target, ...source) {
//校验
MuMerge.validateObject(target, "合并的目标参数必须是一个键值对象");
if (!source.length) return target; //没有要合并的参数返回原值
source.forEach(value => MuMerge.validateObject(value, "被合并的参数必须是一个键值对象"))
//合并
source.forEach(value => {
const valueKeys = MuMerge.getKeys(value);
valueKeys.forEach(key => {
const val = value[key];
if (MuMerge.isObject(val)) { //值为对象
if (!target[key]) target[key] = {};
if (MuMerge.isObject(target[key])) {
target[key] = MuMerge.objectMerge(target[key], val);
} else {
target[key] = MuMerge.deepCopy(val);
}
} else if (MuMerge.isArray(val)) { //值为数组
if (!target[key]) target[key] = [];
if (MuMerge.isArray(target[key])) {
target[key] = MuMerge.arrayMerge(target[key], val);
} else {
target[key] = MuMerge.deepCopy(val);
}
} else {
target[key] = val;
}
})
});
return target;
},
//数组合并
arrayMerge(target, ...source) {
//校验
MuMerge.validateArray(target, "合并的目标对象必须是一个数组对象");
if (!source.length) return target; //无合并对象,返回
source.forEach(value => MuMerge.validateArray(value, "被合并的对象必须是一个数组"));
//合并
source.forEach(value => {
value.forEach((item, index) => {
if (MuMerge.isObject(item)) {
if (!target[index]) target[index] = {};
if (MuMerge.isObject(target[index])) {
target[index] = MuMerge.objectMerge(target[index], item);
} else {
target[index] = MuMerge.deepCopy(item);
}
} else if (MuMerge.isArray(item)) {
if (!target[index]) target[index] = [];
if (MuMerge.isArray(target[index])) {
target[index] = MuMerge.arrayMerge(target[index], item);
} else {
target[index] = MuMerge.deepCopy(item);
}
} else {
target[index] = item;
}
});
});
return target;
},
//深拷贝
deepCopy(data) {
if (!MuMerge.isArray(data) && !MuMerge.isObject(data)) return data;
const weakMap = new WeakMap();
function copy(data) {
if (weakMap.has(data)) return null; //打断施法
const copyData = data instanceof Array ? [] : {};
weakMap.set(data, true);
for (let [key, value] of Object.entries(data)) {
copyData[key] = typeof value === "object" ? copy(value) : value;
};
return copyData;
}
return copy(data);
},
//对象校验
validateObject(value, message = "") {
if (!MuMerge.isObject(value)) {
throw new Error(`${message ? message : '参数必须是一个键值对象'},参数:${value}`)
}
},
//数组校验
validateArray(value, message = "") {
if (!MuMerge.isArray(value)) {
throw new Error(`${message ? message : '参数必须是一个数组对象'},参数:${value}`)
}
},
//获取键数组
getKeys(value) {
return Object.keys(value);
},
//是否对象
isObject(value) {
return MuMerge.getType(value) === "object";
},
//是否数组
isArray(value) {
return MuMerge.getType(value) === "array";
},
//获取数据类型
getType(value) {
const type = typeof value;
if (type !== "object") return type;
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
},
}
const merge = MuMerge.merge;
const cloneMerge = MuMerge.cloneMerge;
export {
merge,
cloneMerge,
}
export default merge;
使用:
import MuMerge,{meage,cloneMerge} from "MuMerge";
const obj1 = {value:1};
const obj2 = {value:2};
const obj3 = MuMerge(obj1,obj2); //{value:2};
console.log(obj3===obj1); //true
const obj4 = cloneMerge(obj1,obj2); //{value:2};
console.log(obj4===obj1); //false
MuMerge === meage; //true
分类:
JavaScript
标签:
javascript对象合并合并深度合并克隆
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据