In code reuse mode, there is a "copy attribute pattern" (copying properties). When it comes to code reuse, it's possible to think of code inheritance (inheritance), but it's important to remember its final goal--we'll reuse the code. Inheritance is just a means of implementing code reuse, not the only way. Copying a property is also a reuse pattern, which is different from inheritance. In this mode, the object gets the member from another object, by simply copying it . As with jquery, it has a $.extend () method that can be used to replicate properties in addition to third-party plugins. Let's take a look at a extend () function implementation Code (note here is not the source of jquery, just a simple example):
functionExtend (parent, child) {vari; //If you do not pass in the second parameter , child //then create a new objectChild = Child | | {}; //Traverse all properties of a parent object //and filter the properties on the prototype //then copy the properties of itself onto the child object for(Iinchparent) { if(Parent.hasownproperty (i)) {Child[i]=Parent[i]; } } //returns the target object child returnChild ;}
The above code is a simple implementation that iterates through the members of the parent object and copies it to the child object. Let's use the Extend () method above to test it:
var dad = {name: "Adam"}; var kid =//Adam
We found that the extend () method is working properly. But there is a problem, given above is a so-called shallow copy (shallow clone). When you use shallow copy, if you change the properties of a child object and it happens to be an object, this action also modifies the parent object, which is not the result we want in many cases alone . Consider the following scenarios:
var dad = { counts: [1, 2, 3], true}}; var // call the Extend () method to copy the properties of Dad to Kid // Append 4 to the kid.counts array // [1, 2, 3, 4]
From the above example, we will find that after modifying the Kid.counts property (appending the element 4), the dad.counts will also be affected. this is because when using shallow copy, because objects are passed by reference, Kid.counts and dad.counts point to the same array (or in memory they point to the same heap address).
Next, let's modify the Extend () function to achieve deep replication. all we need to do is check every property of the parent object, and if that property happens to be an object, then recursively copy the property of that object. In addition, it is necessary to detect whether the object is an array, because the literal creation of the array is different from the object's literal creation, which is [] and the latter is {}. The detection array can be detected using the Object.prototype.toString () method, which, if it is an array, returns "[Object array]". Let's take a look at the deep copy version of the Extend () function:
functionExtenddeep (parent, child) { Child= Child | | {}; for(varIinchparent) { if(Parent.hasownproperty (i)) {//detects whether the current property is an object if(typeofParent[i] = = = "Object") { //if the current property is an object, also to detect if it is an array //This is because the literal representation of the array and the literal representation of the object are different //The former is [], and the latter is {}Child[i] = (Object.prototype.toString.call (parent[i]) = = = "[Object Array]")? [] : {}; //Recursive call ExtendExtenddeep (Parent[i], child[i]); } Else{Child[i]=Parent[i]; } } } returnChild ;}
Well, the deep copy of the function has been written, the following test to see if you can expect to work, that is, whether deep replication can be achieved:
varDad ={counts: [1, 2, 3], reads: {paper:true}};varKid =Extenddeep (dad);//Modify kid's counts property and reads propertyKid.counts.push (4); Kid.reads.paper=false; Console.log (kid.counts);//[1, 2, 3, 4]Console.log (Kid.reads.paper);//falseConsole.log (dad.counts);//[1, 2, 3]Console.log (Dad.reads.paper);//true
From the above example, we can find that even if we modify the kid.counts and kid.reads of the child objects, the dad.counts and kid.reads of the parent object are not changed, so our purpose is implemented.
Here's a summary of the basic ideas for implementing deep replication:
1. Detect if the current property is an object
2. Because the array is a special object, it is also necessary to detect if the property is an array if it is an object.
3. If it is an array, create an empty array, otherwise create an {} empty object and assign the value to the current property of the child object. The Extenddeep function is then called recursively .
The above example allows us to use the recursive algorithm to implement a deep replication method. In fact, the two methods provided by ES5 's new JSON object also allow for deep copying, json.stringify () and Json.parse (), which convert the object to a string, while the latter converts the string into an object. Here we use this method to implement a deep copy of the function:
functionExtenddeep (parent, child) {varI, proxy; Proxy= Json.stringify (parent);//Convert a Parent object to a stringProxy = Json.parse (proxy)//converts a string to an object, which is a copy of the parent Child= Child | | {}; for(Iinchproxy) { if(Proxy.hasownproperty (i)) {Child[i]=Proxy[i]; }} Proxy=NULL;//because proxy is an intermediate object, it can be recycled returnChild ;}
Here are the test examples:
varDad ={counts: [1, 2, 3], reads: {paper:true}};varKid =Extenddeep (dad);//Modify kid's counts property and reads propertyKid.counts.push (4); Kid.reads.paper=false; Console.log (kid.counts);//[1, 2, 3, 4]Console.log (Kid.reads.paper);//falseConsole.log (dad.counts);//[1, 2, 3]Console.log (Dad.reads.paper);//true
The test found that it also enables deep replication. It is generally recommended to use this method, since Json.parse and json.stringify are built-in functions that can be processed faster. In addition, the previous method uses recursive invocation, and we all know that recursion is a low-efficiency algorithm.
Well, it's written here about the deep copy. I am also learning while summing up here, if there are errors, please ask.
Drill down into how JavaScript achieves deep cloning