循环访问嵌套对象,如果不存在,则从其他对象复制值



我有一个很复杂的问题,我想不出答案。在我的Discord bot中,我有一个小对象叫config。我还有一个baseConfig对象,这是将bot添加到新服务器时使用的默认值。有时,我以一种需要新的配置值的方式更新我的bot -我希望能够将其添加到baseConfig并在config中反映新键。(在现实中,配置对象有不同公会的嵌套对象,但我是以一种不相关的方式写的)。例如,假设obj1是一个配置,obj2是基本配置。

let obj1 = {
emojiSettings: {
success: ":success:",
error: ":error:"
},
warnSettings: {
muteThreshold: 3,
expireHours: 48
}
}

假设我用一个全新的配置更新obj2:

// defaults
let obj2 = {
emojiSettings: {
success: ":defaultSuccess:"
error: ":defaultError:"
}
warnSettings: {
muteThreshold: 2,
expireHours: 24
}
newConfig: {
newOption: 4
}
}

我希望obj1中的所有设置保持不变,但添加在obj2中更新的对象和键。

更新

一个比我下面建议的简单得多的解决方案是使用对象解构。有一个基本配置对象和一个自定义配置对象连接到一个计算配置对象,这是你实际使用的可能是明智的(所以你的自定义配置设置可以保存和更新以后),虽然你也可以重新分配配置,如果你喜欢。

首先传递基本配置以将其所有属性应用于配置对象,然后传递配置以更新不同的字段。

const computedConfig = {...baseConfig, ...customConfig}
// Or, if you don't want a third object:
obj1 = {...obj2, ...obj1}

老回答

我要写一个函数深入比较两个,遍历每一个属性。如果属性在obj1中不存在,它就添加它。如果属性确实存在于obj1中,它会检查该属性是否为对象(但不是数组),如果是,则该函数递归调用自身以确保所有对象的属性也存在于obj1中。

const updateObject = (o1, o2) => {
Object.entries(o2).forEach((prop) => {
const propName = prop[0];
if (!o1[propName]) {
if (typeof o2[propName] !== 'object' || Array.isArray(o2[propName])) {
o1[propName] = o2[propName];
} else {
o1[propName] = { ...o2[propName] };
}
} else if (typeof o2[propName] === 'object' && !Array.isArray(o2[propName])) {
updateObject(o1[propName], o2[propName]);
}
});
};
updateObject(obj1, obj2);

最新更新