Simple analysis: A shallow copy is a copy of a layer, deep-seated object-level copy of the reference; a deep copy is a multilayer copy, and each level of data is copied;
Summary: When a shallow copy of the data is a basic data type, then as the direct assignment of the kind, will be copied itself, if in addition to the basic data type has a layer of objects, then for a shallow copy can only copy its reference, the object changes will be reflected on the Copy object, but the deep copy will copy the multilayer, Even nested objects are copied.
How to implement a shallow copy
The first method of implementing a shallow copy
var obj = { A: "Hello", b:{ A: "World", b:21 }, c:["Bob", "Tom", "Jenny"], d:function () { C7/>alert ("Hello World");} ; function Simpleclone (initalobj) { var obj = {}; for (var i in initalobj) { obj[i] = Initalobj[i]; } return obj;} var cloneobj = Simpleclone (obj); Console.log (CLONEOBJ.A); Console.log (CLONEOBJ.B); Console.log (CLONEOBJ.C); Console.log (CLONEOBJ.D); Change the a,b,c,d in the original object to see if the copied object changes cloneobj.a = "changed"; CLONEOBJ.B.A = "changed"; cloneobj.b.b = 25;CLONEOBJ.C = [1, 2, 3]; CLONEOBJ.D = function () {alert ("changed");}; Console.log (OBJ.A); Helloconsole.log (OBJ.B); {A: "Changed", b:25}, in fact only the object is a copy of the reference type Console.log (OBJ.C); [' Bob ', ' Tom ', ' Jenny ']console.log (OBJ.D); ... alert ("Hello World")
A shallow copy is a copy of a layer, in addition to the object is a copy of the reference type, the other is directly passing the value, has its own memory space
The second way to implement a shallow copy
The Object.assign method in ES6, which Object.assign
是ES6的新函数。Object.assign()
copies the enumerable properties of any number of source objects themselves to the target object, and then returns the target object. However, a Object.assign()
shallow copy is performed, and the copy is a reference to the property of the object, not the object itself.
Object.assign (target, ... sources)
Parameters:
Target: Destination object.
Sources: Any number of source objects.
Return value: The target object will be returned.
var obj1 = { A: "Hello", B: { A: "Hello", b:21 }}, var cloneobj1= object.assign ({}, obj1); cloneObj1. A = "changed"; CLONEOBJ1.B.A = "changed"; Console.log (obj1.a) ; Helloconsole.log (OBJ.B.A); "Changed"
How to implement a deep copy
1. Manual Copy
To copy the properties of an object to another object's properties
var obj1 = {a:10, b:20, c:30};var obj2 = {a:obj1.a, b:obj1.b, c:obj1.c};obj2.b = 100;console.log (obj1);//{A:1 0, b:20, c:30} <--not changed to Console.log (OBJ2);//{a:10, b:100, c:30}
2, the object only one layer, you can use the above:Object.assign()函数
Object.assign({}, obj1)
The idea is to create an empty object {}, and then obj1
copy all the attributes in the past, so the obj2
obj1
same will be the same, and then the modification obj2.b
does not affectobj1。
Because Object.assign
the effect is the same as our manual copy, so the same can only deal with the depth of only one layer of objects, there is no way to do real deep Copy. But consider using it if you want to copy only one layer of the object.
3. Turn into JSON and turn back
Convert the JSON.stringify
object to a string, and then JSON.parse
convert the string to a new object.
var obj1 = {body: {a:10}};var obj2 = Json.parse (json.stringify (obj1)); obj2.body.a = 20;console.log (obj1);//{body: { A:10}} <--not changed to Console.log (OBJ2);//{body: {a:20}}console.log (obj1 = = = Obj2);//Falseconsole.log (obj1.body = = = Obj2.body);//False
This is true deep Copy, and this method is easy to use.
But this method also has a lot of disadvantages, such as it will abandon the object of constructor. After a deep copy, whatever the original constructor of the object, it becomes an object after the deep copy.
The only objects that this method can handle correctly are the Number, String, Boolean, Array, 扁平对象
data structures that can be represented directly by JSON. RegExp objects are not deeply copied in this way.
In other words, only objects that can be converted into JSON
a format can be used like this, as there is function
no way to turnJSON。
4. Recursive copy
function Deepclone (initalobj, finalobj) { var obj = finalobj | | {}; for (var i in initalobj) { if (typeof initalobj[i] = = = ' object ') { obj[i] = (Initalobj[i].constructor = = = Array)? [] : {}; Arguments.callee (Initalobj[i], obj[i]); } else { Obj[i] = Initalobj[i]; } } return obj;} var str = {};var obj = {A: {a: "Hello", b:21}};d eepclone (obj, str); Console.log (STR.A);
The code above does make a deep copy. However, when you encounter two objects that are referenced to each other, a dead loop occurs.
In order to avoid situations in which mutually referenced objects result in a dead loop, you should determine whether to reference the object at the time of the traversal, or exit the loop if it is.
The revised code is as follows:
function Deepclone (initalobj, finalobj) { var obj = finalobj | | {}; for (var i in initalobj) { var prop = Initalobj[i]; Avoid mutually referencing objects that cause a dead loop, such as INITALOBJ.A = Initalobj if (prop = = = obj) { continue; } if (typeof prop = = = ' object ') { obj[i] = (Prop.constructor = = = Array)? [] : {}; Arguments.callee (prop, Obj[i]); } else { Obj[i] = prop; } } return obj;} var str = {};var obj = {A: {a: "Hello", b:21}};d eepclone (obj, str); Console.log (STR.A);
5. Using the Object.create () method
Using var newObj = Object.create (oldobj) directly, you can achieve the effect of deep copy.
function Deepclone (initalobj, finalobj) { var obj = finalobj | | {}; for (var i in initalobj) { var prop = Initalobj[i]; Avoid mutually referencing objects that cause a dead loop, such as INITALOBJ.A = Initalobj if (prop = = = obj) { continue; } if (typeof prop = = = ' object ') { obj[i] = (Prop.constructor = = = Array)? []: Object.create (prop); } else { Obj[i] = prop; } } return obj;}
.
Deep copy and shallow copy of JS