在javascript中使用覆盖合并两个对象

时间:2017-11-21 10:03:52

标签: javascript javascript-objects

我想合并两个对象,覆盖属性但保留未被覆盖的属性。

示例:我有以下对象

const theme = {
 colors: {
  base: '#fff',
  accent: '#ff0000'
 }
}

const themeOverride = {
 colors: {
  accent: '#ff8900'
 }
}

并希望将这些合并在一起以获得

const newTheme = {
  colors: {
   base: '#fff',
   accent: '#ff8900'
  }
}

7 个答案:

答案 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>