There are many ways in which JavaScript implements merging objects, such as:
1, Object.assign
2, Jquery.extend (JQuery is also written in JavaScript, thank you)
3, Lodash series (Lodash.merge, Lodash.assign, etc., as to distinguish themselves to see the document, document address: Https://lodash.com/docs)
4, Immutable.js (Fackbook created an immutable data structure JS Library) of the merge method
Among them, Object.assign is a JavaScript native method, but there are two disadvantages in specific scenarios:
1. Browser compatibility issues
2, only shallow merger (about shallow merger deep merger, code Friends of the said prepared, here is not explained, stamp: https://juejin.im/entry/58df4c8b61ff4b006b131792)
PS: The disadvantage of the specific application scenario is that if the project is running in a high-version browser, and as long as the data structure is shallow merging, then there is no such two problems
In order to implement the merging objects, the above-mentioned jQuery, Lodash, immutable these libraries, it is a bit exaggerated (the project itself needs to use these libraries, when I said nothing)
Okay, get to the point, here's my own implementation of a configurable method for merging multiple objects
functionEXT (options) {return NewEXT.prototype.init (options);} Ext.fn= Ext.prototype ={type:function(o) {returnObject.prototype.toString.call (o). Slice (8,-1). toLowerCase (); }, Typemap: {object:function() { return {}; }, Array:function() { return []; } }, //Default configuration Itemsdefaults: {//whether deep mergeIsdeep:true, //whether to traverse properties on the prototype chain of the merged source objectIncludeprototype:true, //used to make custom corrections for each merge itemForeach:function(target, name, SourceItem) {Target[name]=SourceItem; returnTarget; } }, //merging configuration items into default configuration itemsInit:function(options) { for(Let nameinchoptions) { This. defaults[name] =Options[name]; } return This; }, Merge:function() { let self= This, _default=Self.defaults, I= 1, Length=Arguments.length, Target= Arguments[0] | |{}, source, Targetitem, SourceItem, Titype, Sitype, clone, name; for(; i < length; i++) { //determine if the source object is empty if((Source = Arguments[i])! =NULL) { for(Nameinchsource) { //whether to traverse the prototype chain of the source object if(Source.hasownproperty (name) | |_default.includeprototype) {Targetitem=Target[name]; SourceItem=Source[name]; Titype=Self.type (Targetitem); Sitype=Self.type (SourceItem); //prevent loops from appearing if(target = = =SourceItem) { Continue; } //If you are copying an object or an array if(_default.isdeep && SourceItem! =NULL&&Self.typemap[sitype]) {Clone= Targetitem! =NULL&& Titype = = = Sitype?Targetitem:self.typemap[sitype] (); //RecursiveTarget[name] =Self.merge (clone, SourceItem); } Else { //process each merge itemtarget =_default.foreach.call (self, target, name, SourceItem); } } } } } returnTarget; }}; EXT.fn.init.prototype= Ext.fn;
First, define two copies of the data.
functionFoo () { This. A = 1;}functionBar () { This. C = 3;} foo.prototype.b= 2; BAR.PROTOTYPE.D= 4; let data={info: {name:' Leslie ', Age:26, scores: [60, 66, 70, 80]}};let data2={info: {name:' Leslie ', Age:32, scores: [99, 66, 70, {name:' John ', Age:18 }, NewFoo ()]}};
1. General merger
Let target = EXT (). Merge (Data1, data2);
The result is:
2. Custom configuration for merging
Isdeep: Choose whether to deep merge, set to False to only shallow merge, default to True
false }). Merge (Data1, data2);
Includeprototype: Select whether you want to traverse the prototype chain of an object by default to True
false }). Merge (Data1, data2);
ForEach: Custom processing for each merge item
Let target = EXT ({ function(target, name, SourceItem) { = SourceItem + ' Hello, Customize each merge item '; return target; }}). Merge (Data1, data2);
Well, this is how this method is used, how about it? Isn't it flexible? Is it very useful?
But! (The most feared is but) this method is still problematic, do not know that you found in front of the television, that is, when merging New Foo (), the properties of the Foo prototype chain will be copied to the target object, rather than copied to the target object's prototype chain
This problem temporarily did not think of the solution, the back of the thought will be updated, or you have any solution can also leave a message, help solve, finally wish you a happy overtime!
(Fat tiger is my idol)
JavaScript implements a method of merging multiple objects