【问题标题】:Defaults with nested object嵌套对象的默认值
【发布时间】:2020-12-07 07:26:59
【问题描述】:

假设我有以下提供默认值的对象:

default_values = {a: 0, b: 0, c: {aa: 0, bb: 0}}

我还有另一个对象会覆盖其中一些默认值:

override_values = {a: 5, c: {aa: 5}}

我想要的是结合这两个对象,这会导致

combined: {a: 5, b: 0, c: {aa: 5, bb: 0}}

但是,使用像{...default_values, ...override_values} 这样的常规扩展运算符只会给出c: {aa: 5} 而不是c: {aa: 5, bb: 0}。该对象可能很大,因此我无法对所有嵌套对象进行硬编码。

我可以编写一个函数来基本上遍历每个键...如果值不是对象,则使用override | default,否则在嵌套对象上递归调用此函数。但我觉得这很常见,已经有这样的东西了。

【问题讨论】:

  • 只搜索javascript深度合并
  • 您要么明确说明要合并的嵌套对象 ({…, c:{...combined.c, ...override_values.c}}),要么确实编写这样的函数来通用合并任意深度的对象。没有内置的。
  • 可以使用npmjs.com/package/deepmerge等深度合并库
  • lodash 有 _.defaultsDeep lodash.com/docs/4.17.15#defaultsDeep

标签: javascript object default-value


【解决方案1】:

您需要深度合并。

const
    isObject = o => o && typeof o === 'object',
    merge = (a, b) => {
        Object
            .entries(b)
            .forEach(([k, v]) => a[k] = isObject(v) ? merge(a[k] || {}, v) : v);
        return a;
    },
    default_values = { a: 0, b: 0, c: { aa: 0, bb: 0 } },
    override_values = { a: 5, c: { aa: 5 } },
    result = merge(default_values, override_values);

console.log(result);

【讨论】:

    【解决方案2】:

    您正在寻找与 deep_merge 或 merge 类似的东西。 这些函数很广泛,并在lodash 库中提供。

    这是一个例子:-

    function merge(target, source) {
      Object.keys(source).forEach(key => {
        const sourceValue = source[key];
        if (sourceValue) {
          const targetValue = target[key];
          const newValues = merge(targetValue, sourceValue);
          Object.assign(sourceValue, newValues);
        }
      });
    
      Object.assign(target || {}, source);
      return target;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-12
      • 2017-12-09
      • 2020-04-09
      • 2021-02-10
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多