如何将两个含相同键的JavaScript对象合并并保留所有属性?
解决嵌套对象合并时的属性覆盖问题
嘿,这个问题我之前也碰到过!你用Object.assign()没成功,是因为它默认是浅合并——当两个对象有相同的顶层键(比如这里的2018-05-11)时,它会直接用后面对象的对应值覆盖前面的,而不会深入去合并嵌套的属性。
给你几个实用的解决方案:
1. 针对单个日期键的简洁写法
如果只需要处理这一个日期键,用扩展运算符...直接合并嵌套对象最直观:
const posts = {"2018-05-11": {posts: 2}}; const notes = {"2018-05-11": {notes: 1}}; const merged = { "2018-05-11": { ...posts["2018-05-11"], ...notes["2018-05-11"] } }; console.log(merged); // 输出: {"2018-05-11": {posts: 2, notes: 1}}
扩展运算符会把两个子对象的所有属性展开到新对象里,自动合并不重复的属性,完全不会覆盖已有内容。
2. 通用嵌套合并函数(适合多日期键场景)
如果你的数据里有多个日期键,或者需要复用合并逻辑,写一个通用函数更方便:
function mergeNestedDateObjects(objA, objB) { // 先复制第一个对象的所有顶层内容,避免修改原对象 const mergedResult = {...objA}; // 遍历第二个对象的每一个日期键 for (const dateKey in objB) { if (mergedResult[dateKey]) { // 如果该日期键已存在,合并两个子对象的属性 mergedResult[dateKey] = { ...mergedResult[dateKey], ...objB[dateKey] }; } else { // 如果日期键不存在,直接添加到结果里 mergedResult[dateKey] = objB[dateKey]; } } return mergedResult; } // 测试一下多键场景 const posts = {"2018-05-11": {posts: 2}, "2018-05-12": {posts: 3}}; const notes = {"2018-05-11": {notes: 1}, "2018-05-13": {notes: 2}}; const finalMerged = mergeNestedDateObjects(posts, notes); console.log(finalMerged); // 输出: // { // "2018-05-11": {posts: 2, notes: 1}, // "2018-05-12": {posts: 3}, // "2018-05-13": {notes: 2} // }
这个函数能自动处理所有日期键,不管是已有键的嵌套合并,还是新键的添加,都能搞定。
3. 用Object.assign()实现嵌套合并
如果你还是想用Object.assign(),只需要针对嵌套的子对象单独操作就行:
const posts = {"2018-05-11": {posts: 2}}; const notes = {"2018-05-11": {notes: 1}}; // 先复制顶层对象,避免修改原posts const merged = Object.assign({}, posts); // 对嵌套的子对象单独做合并 merged["2018-05-11"] = Object.assign( {}, merged["2018-05-11"], notes["2018-05-11"] ); console.log(merged); // 同样得到目标结果
这里的关键是不要直接合并顶层对象,而是对每个需要保留属性的嵌套子对象单独调用Object.assign()。
总结一下:核心就是要区分顶层对象的合并和嵌套子对象的合并,Object.assign()默认只处理顶层,所以要针对嵌套层单独做合并操作,扩展运算符在这种场景下用起来会更简洁易读。
内容的提问来源于stack exchange,提问作者Zabs
相关产品推荐
相关产品推荐

