2

How do I properly deep merge (lodash like) two ES6 class instances?
The resulting object has to be an actual instance of the same class and its properties should be a deep merge of the two instances' properties.

JeB
  • 11,653
  • 10
  • 58
  • 87
  • Merge, or clone and merge? – Bergi Sep 11 '18 at 20:46
  • `lodash` merge merges without cloning so if I stick with the question definition I would say *merge*. But for me it doesn't actually matter, so it can be *clone* as well. – JeB Sep 11 '18 at 20:48
  • 3
    Possible duplicate of [How to deep merge instead of shallow merge?](https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge) – zero298 Sep 11 '18 at 20:49
  • @zero298 I specifically highlighted the difference, please read the question thoroughly. Not a duplicate at all. – JeB Sep 11 '18 at 20:49
  • What do you mean by **ES6 class instance**? They're still Objects at the end of the day. – zero298 Sep 11 '18 at 20:50
  • 3
    @meltedspark In that case, `_.merge(instance1, instance2)` should just work. Merging new property values into it doesn't change `instance1`s prototype. – Bergi Sep 11 '18 at 20:50
  • @zero298 yes, objects *with constructors* and *methods on prototype* – JeB Sep 11 '18 at 20:52
  • And from which class should the resulting object inherit? – Jonas Wilms Sep 11 '18 at 20:54
  • @Bergi what if I'd like to create a new instance? – JeB Sep 11 '18 at 20:54
  • @JonasWilms the same class mergees inherit from – JeB Sep 11 '18 at 20:55
  • @meltedspark See https://stackoverflow.com/a/16025595/1048572, but in general I recommend giving objects a `.clone()` method that does class-specific stuff – Bergi Sep 11 '18 at 20:56
  • @JonasWilms Sounds like both objects are instance of the same class – Bergi Sep 11 '18 at 20:57
  • @Bergi this one-liner is what I looked for, thank you: `Object.assign(Object.create(Object.getPrototypeOf(o1)), merge(o1, o2))` – JeB Sep 11 '18 at 21:03

1 Answers1

1

If there is no need to create a new instance, the following will do

_.merge(instance1, instance2)

This will deep merge instance2 properties into instance1 while preserving the prototype.


If the merged instance should be a brand new object it is still achievable:

let newInstance = Object.assign(Object.create(Object.getPrototypeOf(o1)), _.merge(o1, o2));

This will create a new object which is an instance of the same class o1 is and will deep merge into it the properties of o1 and o2.
This approach, however, has some caveats, for example (from here):

It's hardly possible if the instance was created with heavy use of closures in the constructor function. We may never now which internal values were set, and how to reproduce such a setup.

JeB
  • 11,653
  • 10
  • 58
  • 87