devDeepMerge 合并两个对象
递归合并两个对象,生成新的对象,且不会修改原始对象, 并根据特定层次或全局的过滤规则过滤指定的属性。 同时,当 obj2 的属性值为 undefined 或 null 时,跳过合并该属性。 过滤逻辑同时作用于 obj1 和 obj2 中的属性。
使用示例
ts
import {devDeepMerge} from 'devecoui-plus';
// 示例对象
const obj1 = {
name: 'Alice',
age: 25,
address: {
city: 'New York',
zip: '10001',
},
preferences: {
theme: 'dark',
notifications: true,
}
};
const obj2 = {
age: 30, // 覆盖 age
address: {
zip: '10002', // 覆盖 zip
street: '5th Avenue',
},
preferences: {
notifications: false, // 覆盖 notifications
},
occupation: 'Engineer', // 新增属性
};
// 过滤规则
const filterRules = {
_all: ['occupation'], // 在所有层级中过滤掉 occupation
address: {
street: true, // 在 address 层级中过滤 street 属性
}
};
// 调用 devDeepMerge
const mergedResult = devDeepMerge(obj1, obj2, filterRules);
console.log(mergedResult);
/**
* 输出
* {
* "name": "Alice",
* "age": 30,
* "address": {
* "city": "New York",
* "zip": "10002"
* },
* "preferences": {
* "theme": "dark",
* "notifications": false
* }
* }
*/
方法源码
ts
/**
* 递归合并两个对象,生成新的对象,且不会修改原始对象,
* 并根据特定层次或全局的过滤规则过滤指定的属性。
* 同时,当 obj2 的属性值为 undefined 或 null 时,跳过合并该属性。
* 过滤逻辑同时作用于 obj1 和 obj2 中的属性。
*
* @param obj1 - 第一个对象,作为合并基准对象
* @param obj2 - 第二个对象,用于覆盖第一个对象的值
* @param filterRules - 可选的过滤规则对象,可以指定某一层要过滤的属性,也可以通过 "_all" 全局过滤所有层级的特定属性
* @returns 返回合并后的新对象
*/
export function devDeepMerge<T extends Record<string, any>, U extends Record<string, any>>(
obj1: T,
obj2: U,
filterRules: Record<string, any> = {}
): T & U {
const result = { ...obj1 }; // 复制 obj1,创建新对象,避免修改原始数据
for (const key in obj2) {
if (obj2.hasOwnProperty(key)) {
const value = obj2[key];
// 跳过 undefined 和 null 的值
if (value === undefined || value === null) {
continue;
}
// 处理全局过滤:检查是否需要在所有层级中过滤某些字段
if (filterRules["_all"] && filterRules["_all"].includes(key)) {
continue; // 跳过全局过滤的字段
}
// 处理局部层级过滤:检查当前层级是否有指定的过滤规则
if (filterRules.hasOwnProperty(key)) {
if (filterRules[key] === true) {
continue; // 跳过局部过滤的字段
}
if (devIsObject(filterRules[key]) && devIsObject(value) && devIsObject(obj1[key])) {
result[key] = devDeepMerge(obj1[key], value, filterRules[key]) as any;
continue;
}
}
// 如果两个都是对象,递归合并
if (devIsObject(obj1[key]) && devIsObject(value)) {
result[key] = devDeepMerge(obj1[key], value, filterRules[key] || {}) as any;
} else {
// 直接覆盖 result 的值,而不是 obj1
result[key] = value;
}
}
}
// 检查并处理 obj1 中的过滤字段
for (const key in obj1) {
if (obj1.hasOwnProperty(key)) {
// 处理全局过滤:检查是否需要在所有层级中过滤某些字段
if (filterRules["_all"] && filterRules["_all"].includes(key)) {
delete result[key]; // 从结果中删除全局过滤的字段
}
// 处理局部层级过滤:检查当前层级是否有指定的过滤规则
if (filterRules.hasOwnProperty(key)) {
if (filterRules[key] === true) {
delete result[key]; // 从结果中删除局部过滤的字段
}
}
}
}
return result as T & U;
}