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

覆写多维数组配置时根键被替换,如何仅更新深层指定属性

问题核心原因

Object.assign 属于浅合并方法,仅会处理对象的第一层键值对,当某个键对应的值是引用类型(对象、数组)时,会直接用传入的新值覆盖原有值,不会深入子层级做合并操作,这就是你现在整个layouts配置被替换的原因。

解决方案

方案1:无第三方依赖,手动实现递归深合并

写一个通用的深合并函数,只在两个值都是纯对象时递归合并,其余情况直接用自定义配置的值覆盖:

function deepMerge(target, source) {
  // 遍历源对象的所有键
  for (const key in source) {
    // 仅处理源对象自身的属性
    if (source.hasOwnProperty(key)) {
      // 如果目标对象、源对象当前键的值都是非数组的纯对象,就递归合并
      if (
        typeof target[key] === 'object' && target[key] !== null &&
        typeof source[key] === 'object' && source[key] !== null &&
        !Array.isArray(target[key]) && !Array.isArray(source[key])
      ) {
        deepMerge(target[key], source[key]);
      } else {
        // 其他情况直接覆盖
        target[key] = source[key];
      }
    }
  }
  return target;
}

使用时替换原来的Object.assign即可:

// 建议先拷贝一份默认配置,避免污染原始默认值
this.settings = deepMerge({...this.defaultSettings}, custom.data.settings);

用你给出的示例测试,合并后layouts.root的原有配置会完整保留,仅layouts.results.view会被更新为Special,符合需求。

方案2:项目已引入Lodash时直接使用现有方法

如果你的项目已经依赖Lodash,直接调用_.merge方法即可,无需自己写工具函数:

import _ from 'lodash';
this.settings = _.merge({}, this.defaultSettings, custom.data.settings);

如果有自定义数组合并的需求,可以使用_.mergeWith自定义合并规则。

注意事项

  • 调用合并前要校验接口返回的自定义配置合法性,避免返回null/非对象值导致合并报错
  • 如果配置中包含Date、RegExp等特殊引用类型,需要在深合并函数中补充对应类型判断,保证合并逻辑符合预期
  • 不要直接修改默认配置的原始对象,合并时第一个参数传入空对象或者默认配置的拷贝,避免原始默认值被污染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:39:03