var obj1 = {
a: 'cat'
b: 'dog'
};
var obj2 = {
b: 'dragon'
c: 'cow'
};
如何从obj2
到obj1
添加属性,而不改写为obj1
。输出应该像console.log(obj1)
=>{a: 'cat', b: 'dog', c: 'cow'}
和console.log(obj2)
=>{b: 'dragon', c: 'cow'}
var obj1 = {
a: 'cat'
b: 'dog'
};
var obj2 = {
b: 'dragon'
c: 'cow'
};
如何从obj2
到obj1
添加属性,而不改写为obj1
。输出应该像console.log(obj1)
=>{a: 'cat', b: 'dog', c: 'cow'}
和console.log(obj2)
=>{b: 'dragon', c: 'cow'}
就检查它是否存在第一,如果它不添加它!
for (key in obj2) {
if (!obj1[key]) obj1[key] = obj2[key]
}
由于RobG在评论中指出,这是不行的,如果你的价值观是falsey(0,假的,不确定的,空,“”,等等),它会跳过他们。如果你总是使用字符串,就像在你的例子这将是确定的,但你很可能会成为安全和全面:
for (key in obj2) {
if (!(obj1.hasOwnProperty(key))) {
obj1[key] = obj2[key]
}
}
从一个对象的属性复制到另一个有Object.assign。但是,如果源上存在相同名称的属性,它将覆盖目标对象的值。
您可以创建一个assignSoft方法,该方法不会覆盖现有属性的值。以下内容基于MDN的Object.assign polyfill。它似乎有点长,因为它尽可能地实现了对于Object.assign的ECMAScript算法。
此外,与内置的Object.assign一样,它只做一个“浅”副本,因此不会复制对象值,因此会分配参考。
if (typeof Object.assignSoft != 'function') {
Object.assignSoft = function(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
// Don't copy if property exists on target
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey) && !Object.prototype.hasOwnProperty.call(to, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
};
}
var obj = Object.assignSoft({a:'a',b:'b'},{b:'bb',c:'c'});
console.log(obj); // {a:'a',b: 'b',c:'c'}
更紧凑(虽然不太严格的)版本,只需要一个源对象。要添加支持多源,遍历传入的参数
if (!Object.assignSoft) {
Object.assignSoft = function(target, source) {
Object.keys(source).forEach(function(key){
if (!target.hasOwnProperty(key)) {
target[key] = source[key];
}
});
return target;
}
}
var obj = Object.assignSoft({a:'a',b:'b'},{b:'bb',c:'c'});
console.log(obj); // {a:'a',b: 'b',c:'c'}
解决方案:
obj1 = {...obj2, ...obj1};
该解决方案只有当你知道什么是预期值可能是工作,例如你知道他们都将是非空字符串。这使用对象扩展语法。您需要确保最后包含obj1
。你可能需要一个像babel这样的转译器,直到所有浏览器(IE ...)都赶上为止。
let obj1 = {
a: 'cat',
b: 'dog'
};
let obj2 = {
b: 'dragon',
c: 'cow'
};
obj1 = {...obj2, ...obj1};
console.log('obj1:', obj1);
console.log('obj2:', obj2);
顺序很重要,IE的任何版本都不支持'...'标点符号。 :-( – RobG
@RobG,我加了一个关于可能需要babel的警告,谢谢。 –
@RobG好点,我会改变我的回答反映这一点。 – AllTheTime
我试过这个,它没有工作。你可以再检查一次吗? –
@ChristAdam它绝对有效...... https://jsfiddle.net/szycsmtc/ – AllTheTime