我想合并两个对象,覆盖属性但保留未被覆盖的属性。
示例:我有以下对象
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
和
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
并希望将这些合并在一起以获得
const newTheme = {
colors: {
base: '#fff',
accent: '#ff8900'
}
}
答案 0 :(得分:4)
如果您只想合并theme和themeOverride的属性颜色,可以通过以下代码完成:
var theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
};
var themeOverride = {
colors: {
accent: '#ff8900'
}
};
Object.assign(theme.colors, themeOverride.colors);
console.log(theme);
答案 1 :(得分:2)
您可以使用Object.assign合并这些对象
更新现有对象
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
Object.assign(theme.colors, themeOverride.colors)
console.log(theme)
或创建新对象
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
newTheme = { colors: Object.assign({}, theme.colors, themeOverride.colors) }
console.log(newTheme)
答案 2 :(得分:2)
您可以通过迭代所有属性进行更新以使用对象的递归方法进行合并。
function merge(target, source) {
Object.keys(source).forEach(function (key) {
if (source[key] && typeof source[key] === 'object') {
merge(target[key] = target[key] || {}, source[key]);
return;
}
target[key] = source[key];
});
}
var theme = { colors: { base: '#fff', accent: '#ff0000' } },
themeOverride = { colors: { accent: '#ff8900' } };
merge(theme, themeOverride);
console.log(theme);

答案 3 :(得分:0)
您可以将reduce与旧theme
一起用作初始值。尝试这样的事情:
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
},
}
const themeOverride = {
colors: {
accent: '#ff8900'
},
border: {
borderWidth: '2px'
}
}
const newTheme = Object.keys(themeOverride).reduce((prev, key) => {
prev[key] = Object.assign({}, theme[key] || {}, themeOverride[key])
return prev
}, Object.assign({}, theme))
console.log(newTheme)

请注意,此解决方案需要最多2级嵌套。
答案 4 :(得分:0)
迭代两个对象,在该实例中查找交集和覆盖;否则,只需复制;
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
window.onload = mergeObjects(theme,themeOverride)
function mergeObjects(base,override) {
var mergedObj = {'colors' : {}};
for(key in base["colors"]) {
if(override['colors'][key] == undefined) {
mergedObj['colors'][key] = base['colors'][key]
}
else {
mergedObj['colors'][key] = override['colors'][key]
}
}
console.log('mergedObject is',mergedObj)
}

答案 5 :(得分:0)
您可以递归查看对象并以这种方式分配新的更新值。
在这里,我为它做了一个功能:
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
function overrideObject(o1,o2){
var res = {};
//Go through all your attributes
for (var a in o1){
//Begin recursive method if another object is detected
if(typeof o1[a] == 'object'){
res[a] = overrideObject(o1[a],o2[a])
}
//Clone old data & update it if necessary
else{
res[a] = o1[a];
if(typeof o2[a] != 'undefined') res[a] = o2[a];
}
}
return res;
}
console.log(overrideObject(theme,themeOverride));

答案 6 :(得分:-1)
JS没有内置的方法可以做到这一点,但是使用Lodash或Underscore的_.merge()
或Ramda的_.mergeDeepLeft()
非常简单,所有这些都递归地合并对象。
const theme = {
colors: {
base: '#fff',
accent: '#ff0000'
}
}
const themeOverride = {
colors: {
accent: '#ff8900'
}
}
const newTheme = _.merge(theme, themeOverride);
console.log(newTheme);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>