The audience for this article
-
First, the business needs of developers who need to know how to deeply copy JS objects.
-
The second type is a good scholar who hopes to have a solid JS foundation and go to the interviewer to show the operation in the future.
For the first group of readers
All you need is one line of hack code for deep copy
At this point copyObj. Arr! == targetobj. arr has implemented deep copy
There are two disadvantages to using window.JSON as a deep copy:
-
If you have a function in your object, it can’t be copied
-
Unable to copy properties and methods on the copyObj object prototype chain
Of course, once you know their weaknesses, if they don’t have an impact on your business needs, you can use them in one line of native code.
Most of my current business scenarios can afford to ignore these two shortcomings. Objects that need to be deeply copied often have no functions in them and do not need to copy properties of their prototype chain.
For the second group of readers
Below I will explain the JS object copy as thoroughly as possible, to explain the clear copy, you need a little bit of pre-knowledge
What you need to know:
-
Understand the difference between reference types and value types in JS and know that Obj stores only references
-
Basic understanding of prototype chain
All about object copying:
1. What are deep copy and shallow copy
2. Common application scenarios of deep copy and shallow copy in services
3. Implementation of deep copy and shallow copy
4. Summary and suggestions
1. What are deep copy and shallow copy
We discuss the premise of deep copy and shallow copy of JS objects
Only in the case of nested objects within the object will we discuss, depending on the requirements, whether we want a deep copy or a shallow copy.
Take an object like the following
Because, if it’s an object like {name: ‘ziwei’} with no nested objects, there’s no need to distinguish between shallow and deep copies. The only difference between a deep copy and a shallow copy is if there are nested objects
What shallow copy looks like (we don’t know how to implement it for now, because we’ll cover it below)
After calling shallowCopy(),obj2 copies all of obj1’s properties. But obj2.arr and obj1.arr are different references to the same memory space
So, when two OBJ are copied, although they have the same properties and are indeed different objects, their internal OBJ points to the same memory space. This is called a shallow copy
What deep copy looks like (we don’t know how to implement it for now, because we’ll cover it below)
After calling deepCopy(),obj2 copies all of obj1’s attributes, and obj2.arr and obj1.arr point to different memory Spaces.
The two obj2s have nothing to do with each other except copy the same property.
Therefore, after copying two OBJ, there is no other correlation except the copy of the same property, which is called deep copy
2. Common application scenarios of deep copy in services
For example, the business requirement is: a table displays various information about the product, and clicking “Agree” will pop up a dialog box to adjust the quantity of the product.
This is where we use deep copies of objects for business purposes. Since the properties of the Commodity table are almost the same as those of the Adjustment Commodity table, we need to copy them.
The following pseudocode and images show the problems with shallow copies
AdjustTableArr and adjustTableArr are all the same in adjustTableArr. So in the adjustTableArr diagram, the red line is adjustTableArr.
When we modify the quantity of the item in the Adjusted Item table, the item table also changes, which is not what we want
In fact, we hope that the data in these two tables are completely independent and do not interfere with each other. The quantity of goods will be updated only after the adjustment is confirmed.
In this case we can use the deep-copy one-line hacks described earlier
Remember its flaws? Functions in the object cannot be copied, and properties in the prototype chain cannot be copied. There is no business impact here, can be very convenient deep copy.
3. Implementation of deep copy and shallow copy
In fact, JQ already has $.extend() function, implementation is deep copy and shallow copy function. Interested partners can also look at the source.
Shallow copy
Shallow copy is simpler, with a for in loop
Deep copy implementation
-
A deep copy is a walk through the copied object
-
Determine the data type of each item in the object
-
If it is not an object type, the assignment is done directly. If it is an object type, deepCopy is called again, recursively.
Source.hasownproperty (key) = source.hasownProperty (key) = source.hasownProperty (key)
That is, I don’t copy the attributes on __proto__. And you can actually add and condition it based on your business needs
(JQ $.extend() copies attributes from __proto__, but directly to the object, not the previous __proto__.)
4. Summary and suggestions
Although you may often use apis provided by the framework to implement deep copy.
Parse () (jSON.parse ()) (json.parse ()))
5. Correct
The vulnerability of the deepCopy method above does not take into account the fact that the source is an array to begin with
Here is a modified version
Author: ziwei3749
https://segmentfault.com/a/119000001282838