JavaScript如何合并对象中相同键名的嵌套对象属性
JS合并对象中同键名嵌套对象的实现方法
注意:JavaScript原生对象字面量不允许存在重复键,如果你直接在代码里写示例中重复定义
foo1的对象,JS解析时会直接用后面的foo1覆盖前面的,代码运行阶段根本拿不到第一个foo1的内容。实际业务场景下这类待合并数据通常以键值对数组、多对象列表的形式存储,下面的实现基于通用场景编写。
浅合并实现(适用于示例中仅一层嵌套的场景)
核心逻辑是遍历所有待合并的键值对,遇到重复键时用对象展开运算符合并子属性,无额外依赖,兼容性好:
/** * 合并同键名的对象属性 * @param {Array<[string, Record<string, any>]>} entries 待合并的键值对数组 * @returns {Record<string, Record<string, any>>} 合并完成后的对象 */ function mergeDuplicateKeys(entries) { const merged = {} for (const [key, subObj] of entries) { // 键已存在则合并子属性,不存在则直接拷贝赋值 merged[key] = merged[key] ? { ...merged[key], ...subObj } : { ...subObj } } return merged } // 调用示例 const rawData = [ ['foo1', { bar1: '1', bar2: '2', bar3: '3' }], ['foo1', { bar4: '4', bar5: '5' }], ['foo2', { bar1: '1', bar2: '2' }] ] const my_obj = mergeDuplicateKeys(rawData)
运行后得到的my_obj和你预期的结构完全一致。
深度合并实现(适用于多层嵌套场景)
如果你的嵌套对象里还有更深层的重复键,浅展开会直接覆盖深层属性,可以用递归实现深度合并:
// 深度合并两个对象 function deepMerge(target, source) { for (const key in source) { // 仅当属性值为普通对象时递归合并,其他类型直接覆盖 if (Object.prototype.toString.call(source[key]) === '[object Object]') { target[key] = target[key] || {} deepMerge(target[key], source[key]) } else { target[key] = source[key] } } return target } function mergeDuplicateKeysDeep(entries) { const merged = {} for (const [key, subObj] of entries) { merged[key] = merged[key] ? deepMerge(merged[key], subObj) : deepMerge({}, subObj) } return merged }
补充说明
- 如果你的待合并数据源是多个独立对象组成的数组,只需要调整遍历逻辑,把每个对象的键值对拆出来传入上述方法即可
- 如果值类型包含数组、日期、自定义类实例,需要根据业务需求调整类型判断和合并逻辑,比如数组可以选择拼接、覆盖等不同处理方式
内容的提问来源于stack exchange,提问作者Laskii
相关产品推荐
相关产品推荐

