【问题标题】:Javascript: Modifying nested object in ES6 shorthandJavascript:在 ES6 速记中修改嵌套对象
【发布时间】:2023-03-11 02:49:01
【问题描述】:

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

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

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() 的结果。或者,您可以使用 lodash 及其 set 方法,因为您现在已经知道要更改的内容。 lodash.com/docs/4.17.11#set
  • const initialvalue = getObject();

标签: javascript ecmascript-6 ecmascript-2016


【解决方案1】:

当在...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);

【讨论】:

    【解决方案2】:

    在我之前的回答的基础上,正如 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);

    【讨论】:

      【解决方案3】:

      您可以尝试以下方法:

      getParentObj(path, obj) {
         return path.split('.').reduce((o,i)=>o[i], obj);
      }
      
      const parent = getParentObj('a.b', getObject());
      parent[d] = 24;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-16
        • 2023-03-21
        • 1970-01-01
        • 2018-04-13
        • 2021-11-16
        • 2020-11-03
        相关资源
        最近更新 更多