JavaScript deep Copy is a beginner or even experienced developer who often encounters problems and does not have a good understanding of the deep copy of JavaScript.
Deep copy (Deepclone)?
And deep copy is relatively shallow copy, many beginners in contact with this gratitude, is very Meng.
Why should I use a deep copy?
In many cases, we all need to assign a value to a variable, give it a value, but when assigning a value type, we just share an area of memory, causing the assignment to remain the same as the previous value.
Look at a concrete example.
Assign the test an object
var test = {
A: ' A ',
B: ' B '
};
Assign test to test2
//At this point test and test2 are sharing the same memory object, which is the shallow copy
var test2 = test;
test2.a = ' A2 ';
TEST.A = = ' A2 '/Is True
Graphic:
This is a good understanding of why reference value type data affects each other.
Realize
To implement a deep copy function, you have to say the numeric type of JavaScript.
determining JavaScript types
JavaScript has the following basic types
The
Type Description
undefined undefined type has only one value undefined, which is the value of the variable when it was not assigned
Null null type also has only one value null, which is an empty object reference
Boolean boolean has two values of true and False
string it represents text information
number It represents digital information
object It is an unordered set of properties, including function functions and array
Use TypeOf to determine function and array, using the Object.prototype.toString method.
[By default, each object inherits the ToString () method from object, and if the method is not overwritten (obscured) by the same method on the object itself or closer to the upper-level prototype, the call to the object's ToString () method returns "[Object Type] ", where the string type represents an object type][1]
function type (obj) {
var toString = Object.prototype.toString;
var map = {
' [object Boolean] ': ' Boolean ',
' [object number] ' : ' number ',
' [Object String] ' : ' String ',
' [Object Function] ': ' Function ',
' [Object Array] ' : ' array ',
' [Object Date] ' : ' Date ',
' [Object RegExp] ' : ' RegExp ',
' [Object Undefined] ': ' Undefined ',
' [Object Null] ' : ' Null ',
' [Object Object] ' : ' object '
};
return Map[tostring.call (obj)];
}
Implement Deepclone
For values of unreferenced value types, the direct assignment, and the reference value type (object) need to be traversed again, recursively assigned.
function Deepclone (data) {
var t = type (data), O, I, ni;
if (t = = = ' array ') {
o = [];
} else if (t = = = ' object ') {
o = {};
} else {return
data;
}
if (t = = = ' array ') {
for (i = 0, ni = data.length i < ni; i++) {
O.push (Deepclone (data[i));
}
return o;
} else if (t = = = ' object ') {for
(I-in data) {
O[i] = Deepclone (Data[i]);
Return o.
}
}
Here's a point. We should note that for the function type, the blogger is directly assigned or shares a memory value. This is because the function is more complete with some functions, there is an input value and a return value, and for the upper level of the business is more to complete the business functions, do not need to actually copy the function deep.
But how do you copy a function type?
In fact, the blogger only thought of using new to operate, but the function will be executed again, dare not imagine what will be the implementation of the results Oh! O (╯-╰) o! Other temporarily do not have any good idea, welcome everybody to guide Oh!
Here almost also achieved the deep copy, and some people feel how did not realize shallow copy?
Shallow copy?
For shallow copies, it can be understood to operate on only one common area of memory! There will be danger here! (。 ﹏。 *)
If you manipulate this shared data directly, you will often receive data anomalies and be changed by other parts without control. So you should not directly manipulate the data source, encapsulate some methods to the data source, to carry on the curd operation to the data.
That's about as far as it goes, but as a front-end, it's not just about JavaScript itself, but about DOM, browsers, and so on.
Element type
Look at the following code, the result will return what?
Object.prototype.toString.call(document.getElementsByTagName('div')[0])
The answer is [object Htmldivelement]
Sometimes the DOM element is saved, the deep copy is accidentally made, and the deep copy function lacks the judgment on element elements. and to judge element elements to use instanceof to judge. Because for different labels, ToString returns a constructor that corresponds to a different label.
function type (obj) {
var toString = Object.prototype.toString;
var map = {
' [object Boolean] ': ' Boolean ',
' [object number] ' : ' number ',
' [Object String] ' : ' String ',
' [Object Function] ': ' Function ',
' [Object Array] ' : ' array ',
' [Object Date] ' : ' Date ',
' [Object RegExp] ' : ' RegExp ',
' [Object Undefined] ': ' Undefined ',
' [Object Null] ' : ' Null ',
' [Object Object] ' : ' object '
};
if (obj instanceof Element) {return
' element ';
}
return Map[tostring.call (obj)];
}
Other ways?
The implementation of jquery
Refer to Https://github.com/jquery/jqu ...
The realization of underscore
Refer to https://github.com/jashkenas/...
The realization of Lodash
Refer to Https://github.com/lodash/lod ...
JSON implementation
A deep copy can be achieved by json.stringify first and then Json.parse. However, data types only support basic numeric types.
var obj = {
A: ' A ',
b:function () {console.log (' B ')}
}
//The function is filtered when json.stringify.
json.stringify (obj)/"{" A ":" A "}"
Summary
Here's a summary of the deep copy and how to implement a deep copy. In different scenarios, depending on the business scenario, decide if you want to use a deep copy.