如何将两个JSON合并成一个:全面指南
在数据处理和开发过程中,经常需要将两个JSON对象合并为一个,无论是配置文件的整合、API数据的拼接,还是前端组件的状态管理,JSON合并都是一项基础且高频的操作,JSON合并并非简单的“拼接”,它需要处理键名冲突、嵌套对象、数组覆盖等多种复杂场景,本文将详细介绍JSON合并的核心方法、常见场景及代码实现,帮助你轻松应对不同合并需求。
JSON合并的核心概念
JSON(JavaScript Object Notation)本质上是一种键值对结构的数据格式,其合并逻辑与编程语言中的对象合并类似,合并两个JSON时,核心规则是:对于相同键名的字段,后续JSON的值会覆盖前者;对于嵌套对象,则递归执行合并;对于数组,根据需求选择覆盖或拼接。
常见合并场景及解决方案
场景1:简单扁平JSON合并(无嵌套对象/数组)
当两个JSON均为“一级结构”(无嵌套对象或数组),合并逻辑最直接:相同键名保留后者的值,不同键名全部保留。
示例
json1 = {
"name": "Alice",
"age": 25,
"city": "New York"
}
json2 = {
"gender": "female",
"age": 26, // 键名冲突,json2覆盖json1
"job": "engineer"
}
合并结果
{
"name": "Alice",
"age": 26,
"city": "New York",
"gender": "female",
"job": "engineer"
}
实现方式(JavaScript)
const json1 = { name: "Alice", age: 25, city: "New York" };
const json2 = { gender: "female", age: 26, job: "engineer" };
// 使用Object.assign()(目标对象为{}时不会修改原对象)
const merged = Object.assign({}, json1, json2);
// 或使用展开运算符(ES6+)
const merged = { ...json1, ...json2 };
console.log(merged);
// 输出: { name: 'Alice', age: 26, city: 'New York', gender: 'female', job: 'engineer' }
场景2:嵌套JSON合并(递归处理子对象)
当JSON包含嵌套对象时,需递归合并子对象:相同键名的子对象继续按规则合并,不同键名的子对象直接保留。
示例
json1 = {
"name": "Bob",
"contact": {
"email": "bob@example.com",
"phone": "123-456-7890"
},
"preferences": {
"theme": "dark",
"language": "en"
}
}
json2 = {
"name": "Bob Smith", // 顶层键名冲突,覆盖
"contact": {
"phone": "987-654-3210", // 子对象键名冲突,覆盖
"address": "123 Main St" // 子对象新增键名,保留
},
"settings": {
"notifications": true
}
}
合并结果
{
"name": "Bob Smith",
"contact": {
"email": "bob@example.com",
"phone": "987-654-3210",
"address": "123 Main St"
},
"preferences": {
"theme": "dark",
"language": "en"
},
"settings": {
"notifications": true
}
}
实现方式(JavaScript递归函数)
function deepMerge(target, source) {
// 遍历source的所有键
for (let key in source) {
if (source.hasOwnProperty(key)) {
// 如果target和source的当前值都是对象,则递归合并
if (
typeof source[key] === "object" &&
source[key] !== null &&
!Array.isArray(source[key]) &&
target[key] &&
typeof target[key] === "object"
) {
target[key] = deepMerge(target[key], source[key]);
} else {
// 否则直接覆盖(包括数组、基本类型)
target[key] = source[key];
}
}
}
return target;
}
const json1 = {
name: "Bob",
contact: { email: "bob@example.com", phone: "123-456-7890" },
preferences: { theme: "dark", language: "en" }
};
const json2 = {
name: "Bob Smith",
contact: { phone: "987-654-3210", address: "123 Main St" },
settings: { notifications: true }
};
const merged = deepMerge({ ...json1 }, json2); // 浅拷贝json1避免修改原对象
console.log(merged);
场景3:数组处理(覆盖或拼接)
JSON中的数组合并需根据业务需求选择策略:直接覆盖(用后者的数组替换前者)或拼接(将后者数组合并到前者)。
示例1:数组覆盖(默认行为)
json1 = {
"hobbies": ["reading", "swimming"],
"skills": ["JavaScript", "Python"]
}
json2 = {
"hobbies": ["gaming"], // 覆盖json1的hobbies
"skills": ["Java"] // 覆盖json1的skills
}
合并结果(覆盖)
{
"hobbies": ["gaming"],
"skills": ["Java"]
}
示例2:数组拼接(需特殊处理)
若希望保留两个数组的元素,需修改合并逻辑:当值为数组时,将两个数组合并为新数组。
json1 = {
"tags": ["frontend", "web"],
"courses": ["JS Basics"]
}
json2 = {
"tags": ["React"], // 拼接到json1的tags
"courses": ["Advanced JS"],
"newField": "value"
}
合并结果(拼接)
{
"tags": ["frontend", "web", "React"],
"courses": ["JS Basics", "Advanced JS"],
"newField": "value"
}
实现方式(数组拼接版)
function deepMergeWithArrayConcat(target, source) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (
Array.isArray(source[key]) &&
target[key] &&
Array.isArray(target[key])
) {
// 如果都是数组,则拼接
target[key] = [...target[key], ...source[key]];
} else if (
typeof source[key] === "object" &&
source[key] !== null &&
!Array.isArray(source[key]) &&
target[key] &&
typeof target[key] === "object"
) {
// 如果都是对象,则递归合并
target[key] = deepMergeWithArrayConcat(target[key], source[key]);
} else {
// 否则直接覆盖
target[key] = source[key];
}
}
}
return target;
}
const json1 = { tags: ["frontend", "web"], courses: ["JS Basics"] };
const json2 = { tags: ["React"], courses: ["Advanced JS"], newField: "value" };
const merged = deepMergeWithArrayConcat({ ...json1 }, json2);
console.log(merged);
// 输出: { tags: ['frontend', 'web', 'React'], courses: ['JS Basics', 'Advanced JS'], newField: 'value' }
场景4:键名冲突处理(自定义优先级)
有时需要自定义合并优先级,始终保留json1的值、或根据键名决定覆盖逻辑,可通过修改合并函数实现。
示例:保留json1的值(json2不覆盖冲突键)
json1 = {
"name": "Charlie",
"config": { "debug": true, "port": 3000 }
}
json2 = {
"name": "Charles", // 冲突,但保留json1的值
"config": { "port": 8080, "host": "localhost" } // config.port冲突,保留json1的值
}
合并结果
{
"name": "Charlie",
"config": { "debug": true, "port": 3000, "host": "localhost" }
}
实现方式(保留前者优先级)
function mergeWithFirstPriority(target, source) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (
typeof source[key] === "object" &&
source[key] !== null &&
!Array.isArray(source[key]) &&
target[key] &&
typeof target[key] ===


还没有评论,来说两句吧...