我有一个带有一些嵌套属性的JavaScript对象,我想根据某些条件对其进行更新。起始对象可能是这样的:
const options = {
formatOption: {
label: 'Model Format',
selections: {
name: 'Specific Format',
value: '12x28',
}
},
heightOption: {
label: 'Model Height',
selections: {
name: 'Specific Height',
value: '15',
}
}
};
我想出了使用的解决方案Object.keys
,reduce
并传播经营者,但我想知道这是否是最好的/更简洁的方式为今天的或是否有更好的办法。我不是在寻找性能最高的选项,而是在寻求“最佳实践”(如果有的话)或更优雅的方法。
编辑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";
向我建议的更简洁的版本是使用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()
单独使用来解决问题。
我不确定这是否是最好的解决方案,但对于普通开发人员来说,它的可读性肯定比我的初次尝试或其他解决方案高。