Native way to merge objects in Javascript

The Javascript object has no merge operation. If you have two objects, say

{a:1, b:2} {c:3, d:4} 

And I want to get

 {a:1, b:2, c:3, d:4} 

As far as I know, you need to iterate over objects. That is, you decide either a left merge strategy or a merge strategy, and then you do something like (simplified)

 for (key in object2) { object1[key] = object2[key]; } 

This is normal. However, Javascript has a call and prototype function. For example, turning arguments into Array can be done using

Array.prototype.slice.call(arguments)

This approach uses existing native code, so it is less susceptible to a stupid programmer and should work faster than a non-native implementation.

Question

Is there a trick to using this prototype / call pattern, perhaps for the Attribute or Node traversal functions of the DOM, or perhaps some of the common String functions to merge your own objects?

The code looks something like this:

var merged = somethingrandom.obscuremethod.call(object1, object2)

And as a result, you will get your own merge without going around.

Possible suboptimal solution

If you can use the constructor property for Object , and then force one object to create the constructor of another object, and then run new on the compound object, you can get the merge for free. But I do not have a clear understanding of all the consequences of the constructor function in javascript to make this call.

Lemma

The same question holds true for Arrays . A common problem is to take, for example, 7 arrays of numbers, and then try to figure out the intersection of these arrays. That is, what numbers exist in all 7 arrays.

You could combine them together, then pretend, and then make a detour, of course. But it would be nice if some general intersection were crossed somewhere, which we can force the array to execute initially.

Any thoughts?

edit:

Halfway there

For an array problem, you can do the following:

array.concat (a, b, c) .sort (). join (':') and then use some complex RegExp capture and replay patterns to go through. The RegExp implementation, if you do not know, runs on a very simple stack-based virtual machine. When you initialize your regular expression, which is really a compilation of the program (RegExp.compile is an outdated JS method). Then the native runs the line quickly. Perhaps you can use this for membership thresholds and get better performance ...

He still does not go all the way.

+47
optimization javascript prototype
Jan 19 2018-11-21T00:
source share
8 answers

My answer to this will be disappointing, but still:

no

not

The reason for this is simple: the implementation of the Resig merge project (or "extension" because it called objects) in jQuery makes the loop exactly the same as in your question. You can see it here . And I dare say that if John Resig does not find a smart built-in way to do this, then simple mortals from stackoverflow will not :)

+23
Jan 19 2018-11-21T00:
source share

Million Dollar Question! I tried to do it differently, and the loop path described above always seemed the dirtiest. ES6 Object.setPrototypeOf() allows you to delegate a property override object to the "default property" object, pretty much doing what you are trying to do, but using Object.setPrototypeOf() has some serious consequences, such as disabling browser compiler optimization for the entire script .

In addition, both in the loop solution and in the solution of Object.setPrototypeOf() you are left with a situation where the "override property" object can mutate the "default property" object:

 defaultObj = { a: [1, 2] } ... overrideObj = { b: 3 } Object.setPrototypeOf(overrideObj, defaultObj); console.log(overrideObj); // {a: [1, 2], b: 3} // Great! ... overrideObj.a.push(4); console.log(defaultObj); // {a: [1, 2, 4]} // Uh-oh. 

You might think that this is not a problem, but let me say that you are using this object as a configuration for a third-party library. Now you pass your default object and all references to it to a third-party library.

A better solution might be to use JSON.stringify and JSON.parse to copy and merge objects. Here's a Gist with an example: https://gist.github.com/spikesagal/6f7822466887f19b9c65

NTN

+3
Nov 06 '15 at 17:37
source share

Not that I knew, no. In addition, you will want to write your merge method as follows:

 function mergeInto(o1, o2) { if (o1 == null || o2 == null) return o1; for (var key in o2) if (o2.hasOwnProperty(key)) o1[key] = o2[key]; return o1; } 
+2
Jan 19 '11 at 21:17
source share

You can do the following using your own JS 1.7, without having to create a framework. Fiddle example (the example is intended only for simple objects - not complex nested objects)

 var obj1 = {a: "a", b: "b"}; var obj2 = {c: "c", d: "d"}; // The magic: ugly but works perfectly var value = (JSON.stringify(obj1).concat(JSON.stringify(obj2))).replace("}{", ","); document.getElementById("lbl1").setAttribute("value", value); // back to object var obj3 = JSON.parse(value); document.getElementById("lbl2").setAttribute("value", obj3.a + " " + obj3.b + " " + obj3.c + " " + obj3.d); 
+1
Aug 15 '13 at 1:45
source share

Using ES6 (ES2015), you can use the Object.assign method:

 var x = {a:1, b:2}; var y = {c:3, d:4}; var z = Object.assign({},x,y); 

Using ES7 (ES2016, Chrome 60+ or โ€‹โ€‹Babel), you can use the Object Distribution Operator :

 var x = {a:1, b:2}; var y = {c:3, d:4}; var z = {...x, ...y}; 
+1
Aug 11 '17 at 18:32
source share

ECMA-Script does not have its own paths, use:

 function merge(o1,o2) { if (typeof(o1)!=='object') o1={}; if (typeof(o2)!=='object') o2={}; for (var k in o2) { if (o1[k]!==undefined) alert ('Collision Error'); // TODO else o1[k]=o2[k]; } return o1; } 
0
Apr 7 '14 at 7:09
source share

Here is a feature you can use to solve your dilemma.

the code:

  var a = {'a':'1', 'b':'2'}; var b = {'c':'3', 'd':'4'}; function appendObj(a,b) { var aZ = 'abcdefghijklmnopqrstuvwxyz'.split(''); bKeys = Object.keys(b); for (var i = 0; i < bKeys.length; i++) { a[bKeys[i]] = b[bKeys[i]]; } return a; } var newObj = appendObj(a,b); console.log(newObj) 

Hope this helps.

Note I entered this through my phone, so I apologize if there are semantic errors or typos.

All the best

Matt

-one
Sep 07 '17 at 17:32
source share

Below I have included the deep merge function that I wrote. This will not lead to a deep union of arrays, but only to objects. He will take two objects and return a third, new object.

 var merge = function(o1, o2) { var o_new = {}; for(p in o1) { if(o1[p]) { if(typeof o1[p] == 'object' && !(o1[p] instanceof Array) && o2.hasOwnProperty(p)) { o_new[p] = merge(o1[p], o2[p]); } else { o_new[p] = o1[p]; } } } for(p in o2) { if(typeof o2[p] == 'object' && !(o2[p] instanceof Array) && o1.hasOwnProperty(p)) { o_new[p] = merge(o1[p], o2[p]); } else { o_new[p] = o2[p]; } } return o_new; } 
-2
Oct 20 '16 at 2:47
source share



All Articles