1

Given

var obj1 = {
  a: 'cat'
  b: 'dog'
};
var obj2 = {
  b: 'dragon'
  c: 'cow'
};

How can I add properties from obj2 to obj1 without overwrite to obj1. The output should be like console.log(obj1) => {a: 'cat', b: 'dog', c: 'cow'} and console.log(obj2) => {b: 'dragon', c: 'cow'}

3 Answers 3

7

Solution:

obj1 = {...obj2, ...obj1};

This solution only works if you know what the expected values might be, e.g. you know they will all be non-empty strings. This uses object spread syntax. You need to ensure that you include obj1 last. You may need a transpiler such as babel until all the browsers (IE...) catch up.

let obj1 = {
  a: 'cat',
  b: 'dog'
};
let obj2 = {
  b: 'dragon',
  c: 'cow'
};
obj1 = {...obj2, ...obj1};
console.log('obj1:', obj1);
console.log('obj2:', obj2);

Sign up to request clarification or add additional context in comments.

2 Comments

Order is important, and the ... punctuator is not supported by any version of IE. :-(
@RobG, I added a caveat about possibly needing babel. Thanks.
2

Just check if it exists first and if it doesn't add it!

for (key in obj2) {
    if (!obj1[key]) obj1[key] = obj2[key]
}

As RobG pointed out in the comments, this won't work if your values are falsey (0, false, undefined, null, '', etc.) and it will skip past them. If you are always using strings, like in your example it will be ok, but you might as well be safe and comprehensive:

for (key in obj2) {
    if (!(obj1.hasOwnProperty(key))) {
        obj1[key] = obj2[key]
    }
}

1 Comment

I tried this and it didnt work. Can u check it again?
0

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'}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.