合并 JSON 对象对于组合配置、更新数据和处理默认值至关重要。以下是您应该了解的策略。
使用展开运算符浅合并
const defaults = { theme: "light", lang: "en", fontSize: 14 };
const user = { theme: "dark", fontSize: 16 };
const merged = { ...defaults, ...user };
// { theme: "dark", lang: "en", fontSize: 16 }
第二个对象的属性会覆盖第一个。
Object.assign()
const merged = Object.assign({}, defaults, user);
与展开运算符行为相同,但如果不加 {},会修改目标对象。
深度合并
浅合并无法处理嵌套对象:
// 浅合并丢失嵌套数据
const a = { config: { theme: "light", lang: "en" } };
const b = { config: { theme: "dark" } };
const shallow = { ...a, ...b };
// { config: { theme: "dark" } } — lang 丢失了!
深度合并递归组合嵌套对象:
function deepMerge(target, source) {
const result = { ...target };
for (const key of Object.keys(source)) {
if (isObject(target[key]) && isObject(source[key])) {
result[key] = deepMerge(target[key], source[key]);
} else {
result[key] = source[key];
}
}
return result;
}
const deep = deepMerge(a, b);
// { config: { theme: "dark", lang: "en" } } — lang 保留了!
数组合并策略
当两个对象都有数组时:
// 替换(默认行为)
const replace = { ...a, items: b.items };
// 连接
const concat = { ...a, items: [...a.items, ...b.items] };
// 按 ID 合并
const mergeById = {
...a,
items: a.items.map(item => {
const override = b.items.find(i => i.id === item.id);
return override ? { ...item, ...override } : item;
})
};
使用库
生产代码建议使用成熟的库:
使用我们的 JSON 格式化器 格式化合并结果以便检查。