3

Say I have two objects:

let obj1 = {
  name: 'obj 1',
  id: 1,
  color: "#fff",
  pages: []
}

let obj2 = {
  name: 'obj 2',
  id: 2,
  color: "#ddd"
}

I want to write a function that follows this logic 'loop through obj1, and if both obj1 and obj1 have the same property, update obj1's property with obj2's value'

So result would return obj1 with the value:

{
  name: 'obj 2',
  id: 2,
  color: "#ddd",
  pages: []
}

I'm having a bit of an issue dealing with objects since I can't forEach or map them.

halfer
  • 19,824
  • 17
  • 99
  • 186
cup_of
  • 6,397
  • 9
  • 47
  • 94
  • Just a little heads up, although Object.assign is the most cleaner way to achieve your objective, but I just wanted to point out this: " since I cant forEach or map them". Well, you CAN. You can loop through an object's properties. The objects in JS are a key value pair, so I have to do foreach, I can do Object.keys(obj1).forEach(key => { /* and I can do obj1[key] = obj2[key] here*/ }); – Oo-_-oO Apr 14 '19 at 05:01
  • Possible duplicate of [How can I merge properties of two JavaScript objects dynamically?](https://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically) – adiga Apr 14 '19 at 05:09

4 Answers4

2

You can use

var a = [obj1,obj2];
 obj1 = Object.assign(...a);

let obj1 = {
  name: 'obj 1',
  id: 1,
  color: "#fff",
  pages: []
}

let obj2 = {
  name: 'obj 2',
  id: 2,
  color: "#ddd"
}
var a = [obj1,obj2];
obj1 = Object.assign(...a);
console.log(obj1)
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
1

Your question implies that you don't want to copy properties from obj2 to obj1 which don't exist in obj1. If that can never be the case (i.e. obj2 is always a subset of obj1), then Object.assign is indeed the best way.

If obj2 can have properties you don't want to copy, here is a simply for loop:

for (const prop in obj2) {
  if (prop in obj1) {
    obj1[prop] = obj2[prop];
  }
}

This will iterate over all enumerable properties of the object, including "inherited" ones from its prototype.

If you want to limit this an object's own properties, you can use Object.keys:

for (const prop of Object.keys(obj2)) {
  if (prop in obj1) {
    obj1[prop] = obj2[prop];
  }
}

Note that either approach will only copy "normal" properties. Properties that are symbols have to be handled separately via Object.get​OwnProperty​Symbols.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

You can use spreading like so:

let obj1 = {
  name: 'obj 1',
  id: 1,
  color: "#fff",
  pages: []
}

let obj2 = {
  name: 'obj 2',
  id: 2,
  color: "#ddd"
}

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

console.log(obj1);

(The properties may be in the wrong order as JavaScript object properties are unordered).

You could also use Object.assign:

let obj1 = {
  name: 'obj 1',
  id: 1,
  color: "#fff",
  pages: []
}

let obj2 = {
  name: 'obj 2',
  id: 2,
  color: "#ddd"
}

obj1 = Object.assign(obj1, obj2);

console.log(obj1);
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

This ensures that obj1 only gets updates from obj2 and not any new properties:

let obj1 = {
  name: 'obj 1',
  id: 1,
  color: "#fff",
  pages: []
}

let obj2 = {
  name: 'obj 2',
  id: 2,
  color: "#ddd",
  somethingElse: 'will not add this'
}

const result = Object.entries(obj1).reduce((a, c) => {
  a[c[0]] = obj2[c[0]] !== undefined ? obj2[c[0]] : c[1];
  return a;
}, {});

console.log(result);
Brian Adams
  • 43,011
  • 9
  • 113
  • 111
  • thank you for this answer! seems to work, although the other answers are alot cleaner. do you see any issues with the other answers like obj1 will get new properties as you mentioned? – cup_of Apr 14 '19 at 04:41
  • 1
    just depends on what you need...if `obj1` shouldn't ever pick up new properties from the update then you'll need an approach like this. If it doesn't matter than the spread syntax approach is fine @cup_of – Brian Adams Apr 14 '19 at 04:45