Given
var obj1 = {
a: \'cat\'
b: \'dog\'
};
var obj2 = {
b: \'dragon\'
c: \'cow\'
};
How can I add properties from obj2
to
To copy properties from one object to another there is Object.assign. However, it will overwrite the values of the target object if a same–named property exists on the source.
You could create an assignSoft method that does not overwrite the values of existing properties. The following is based on the Object.assign polyfill at MDN. It seems a bit long because it implements the ECMAScript algorithm for Object.assign as closely as it can.
Also, like the built–in Object.assign, this only does a "shallow" copy so object values are not copied, a reference is assigned.
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'}
A more compact (though less strict) version that only takes one source object. To add support for multiple sources, iterate over the arguments passed in.
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'}