温馨提示:本文翻译自stackoverflow.com,查看原文请点击:ecmascript 6 - What's the best way of creating a new object with updated nested properties in modern JavaScript
ecmascript-6 functional-programming javascript

ecmascript 6 - 在现代JavaScript中使用更新的嵌套属性创建新对象的最佳方法是什么

发布于 2020-03-27 15:46:57

我有一个带有一些嵌套属性的JavaScript对象,我想根据某些条件对其进行更新。起始对象可能是这样的:

const options = {
    formatOption: {
        label: 'Model Format',
        selections: {
            name: 'Specific Format',
            value: '12x28',
        }
    },
    heightOption: {
        label: 'Model Height',
        selections: {
            name: 'Specific Height',
            value: '15',
        }
    }
};

我想出了使用的解决方案Object.keysreduce并传播经营者,但我想知道这是否是最好的/更简洁的方式为今天的或是否有更好的办法。我不是在寻找性能最高的选项,而是在寻求“最佳实践”(如果有的话)或更优雅的方法。

编辑30/01/20
正如所作的评论中指出@CertainPerformance我的代码是变异的原始选项的变量,所以我改变了线const option = options[key];const option = { ...options[key] };我希望这是正确的,并且该函数不会使原始数据变异。

const newObject = Object.keys(options).reduce((obj, key) => {
  const option = { ...options[key] };
  const newVal = getNewValue(option.label); // example function to get new values
    // update based on existence of new value and key
    if (option.selections && option.selections.value && newVal) {
      option.selections.value = newVal;
    }
    return {
      ...obj,
      [key]: option,
    };
}, {});

getNewValue是我正在调用的函数的发明名称,目的是为了获取所查看值的“更新”版本。为了再现了我的情况,你可以只更换线const newVal = getNewValue(option.label);const newVal = "bla bla";

查看更多

查看更多

提问者
Giorgio Tempesta
被浏览
77
Giorgio Tempesta 2020-02-07 01:28

向我建议的更简洁的版本是使用forEach()代替reduce()在这种情况下,唯一困难的部分是克隆原始对象。一种方法是使用lodash的_.cloneDeep(),但是有很多选择(请参阅此处)。

这是代码:

const newObject = _.cloneDeep(options);
Object.keys(newObject).forEach(key => {
    const newVal = getNewValue(newObject[key].label); // example function to get new values
    // update based on existence of new value and key
    if (newObject[key].selections && newObject[key].selections.value && newVal) {
        newObject[key].selections.value = newVal;
    }
});

唯一的问题是forEach()更改了在函数外部声明的值,但reduce()可以更改其参数(就像我最初的解决方案中发生的那样),因此不能reduce()单独使用解决问题

我不确定这是否是最好的解决方案,但对于普通开发人员来说,它的可读性肯定比我的初次尝试或其他解决方案高。