You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现JavaScript递归合并对象与数组且保留原属性?

解决方案:递归合并对象与数组的函数

直接上能解决问题的合并函数:

function deepMerge(target, source) {
  // 源为非对象/数组时,直接返回源(符合更新覆盖逻辑)
  if (source === null || typeof source !== 'object') {
    return source;
  }
  // 处理数组场景
  if (Array.isArray(target)) {
    if (Array.isArray(source)) {
      // 遍历原数组,仅合并源数组对应索引存在的元素
      return target.map((item, index) => {
        return source[index] !== undefined ? deepMerge(item, source[index]) : item;
      });
    }
    // 禁止非数组覆盖数组,避免意外类型转换
    throw new Error('Cannot merge non-array into array');
  }
  // 处理对象场景
  if (typeof target === 'object' && typeof source === 'object') {
    const merged = { ...target };
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        merged[key] = deepMerge(target[key], source[key]);
      }
    }
    return merged;
  }
  // 其他非常规场景,直接返回源
  return source;
}

关键逻辑说明

  1. 数组的精准处理:

    • 仅当原目标和更新源都是数组时,才按索引递归合并元素:
      • 对象数组:合并对应索引的对象属性,原对象的connections等属性不会丢失
      • 字符串/基本类型数组:仅替换源中存在索引的元素,不会把数组转成索引键对象
    • 若尝试用非数组更新数组,直接抛出错误,避免意外类型污染
  2. 对象属性的完整保留:

    • 先复制原对象的所有属性到新对象,再遍历更新源的属性进行递归合并,确保原对象属性不会被覆盖丢失
  3. 基本类型的更新逻辑:

    • 更新源为基本类型时,直接覆盖原目标值,符合常规数据更新的预期

测试示例

对象数组合并(保留原属性)

const original = {
  users: [
    { id: 1, name: 'Alice', connections: ['a', 'b'] },
    { id: 2, name: 'Bob' }
  ]
};

const update = {
  users: [
    { id: 1, age: 30 }
  ]
};

const result = deepMerge(original, update);
// result.users[0] → { id:1, name:'Alice', connections:['a','b'], age:30 }
// result.users[1] → { id:2, name:'Bob' }(完整保留)

字符串数组(避免转成对象)

const original = { tags: ['js', 'mongodb'] };
const update = { tags: ['node'] };

const result = deepMerge(original, update);
// result.tags → ['node', 'mongodb'](未被转成索引对象)

问题根源分析

  • 原数组对象属性丢失:之前的函数未正确处理数组内的对象,直接替换了数组元素而非递归合并对象属性
  • 字符串数组转索引对象:之前的函数误将数组当作普通对象处理,遍历索引作为对象键,导致数组被转换为键值对结构

内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:10:40