Javascript: 在 ES6 中修改嵌套对象 shorthand

Javascript: Modifying nested object in ES6 shorthand

考虑一个函数 returns 一个嵌套对象,我想修改嵌套对象内部的 属性。

在下面的例子中,我多次调用函数或者我需要将它存储在一个临时变量中。有没有办法在大括号内只调用一次,在同一对象内多次调用 spread/modify。

const getObject = () => {
   return {
     a: {
      b: {
        c: 1,
        d: 2,
      }
     },
     e: 3
   }
}

var modifiedD = {
  ...getObject(),
  a: {
     b: {
      ...getObject().a.b,
      d: 4
     }
  }
}

console.log(modifiedD);

...getObject() 之后声明 a 键时,它会替换整个值。它不会合并 a.

后面的内部对象

所以你可以像你做的那样做并多次调用 getObject()


另一种解决方案可能是使用您自己的合并对象的函数来处理它,例如:

function mergeObjects(obj1, obj2) {
  // We are going to copy the value of each obj2 key into obj1
  Object.keys(obj2).forEach((x) => {
    // If we have an object, we go deeper
    if (typeof obj2[x] === 'object') {
      if (obj1[x] === void 0) {
        obj1[x] = {};
      }

      mergeObjects(obj1[x], obj2[x]);
    } else {
      obj1[x] = obj2[x];
    }
  });
  
  return obj1;
}

const getObject = () => {
  return {
    a: {
      b: {
        c: 1,
        d: 2,
      }
    },
    e: 3
  }
}

const modifiedD = mergeObjects(getObject(), {
  a: {
    b: {
      d: 4,
    },
  },
});

console.log(modifiedD);

警告,我制作的函数改变了可能不是最佳答案的对象


或者只调用一次,然后像这样一个一个地设置键:

const getObject = () => {
   return {
     a: {
      b: {
        c: 1,
        d: 2,
      }
     },
     e: 3
   }
}

const modifiedD = getObject();

modifiedD.a.b.d = 4;

console.log(modifiedD);

您可以尝试以下方法:

getParentObj(path, obj) {
   return path.split('.').reduce((o,i)=>o[i], obj);
}

const parent = getParentObj('a.b', getObject());
parent[d] = 24;

除了我之前的回答,正如 Grégory NEUT 指出的那样,您的复杂性可能会大得多。

如果是这样,您可以简单地创建两个对象,然后将它们合并。我发现 function code snippet 可以使用 Object.assign

来做到这一点

示例:

const getObject = () => {
   return {
     a: {
      b: {
        c: 1,
        d: 2,
      }
     },
     e: 3
   }
}

var modifiedD = getObject();
var newD = {
  a: {
     b: {
       d: 4
     },
     y: 1
  },
  z: 20
}

/** TAKEN FROM https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6 **/
// Merge a `source` object to a `target` recursively
const merge = (target, source) => {
  // Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
  for (let key of Object.keys(source)) {
    if (source[key] instanceof Object) Object.assign(source[key], merge(target[key], source[key]))
  }

  // Join `target` and modified `source`
  Object.assign(target || {}, source)
  return target
}

modifiedD = merge(modifiedD, newD);

console.log(modifiedD);