preface
Both deep copy and shallow copy are for reference data types only. The shallow copy copies the object member by member, but only the memory address, not the object itself. The old and new object members still share the same memory. Deep copy creates an identical object. The new object does not share memory with the original object, and changes to the new object will not change to the original object.
JS data type:
- Basic data types: Boolean, String, Number, NULL, undefined
- Reference data types: Object, Array, Function, RegExp, Date, etc
Replication of data types: Replication of basic data types, passed by value
var a = 1;
var b = a;
b = 2;
console.log(a); / / 1
console.lob(b); / / 2
Copy the code
A copy of a reference data type is passed by reference
var obj1 = {
a: 1;
b: 2;
};
var obj2 = obj1;
obj2.a=3;
console.log(obj1.a); / / 3
console.log(obj2.a); / / 3
Copy the code
JS shallow copy
Shallow copy is a bitwise copy of an object. It creates a new object and copies its members in sequence. If the property is of a primitive type, the value of the primitive type is copied. If the attribute is a reference type, the memory address is copied. So if an object member in the new object changes its address, it affects the original object.
// Write a shallow copy
function shallowCopy(obj1) {
let obj2 = Array.isArray(obj1) ? [] : {}
for (let i in obj1) {
obj2[i] = obj1[i]
}
return obj2
}
var obj1 = {
'name' : 'zhangsan'.'language' : [1[2.3], [4.5]],};var obj2 = shallowCopy(obj1);
obj2.name = "lisi";
obj2.language[1] = ["二"."Three"];
console.log('obj1',obj1)
console.log('obj2',obj2)
Copy the code
Shallow copy implementation
The object.assign () method copies any number of enumerable attributes of the source Object to the target Object and then returns the target Object. However, object.assign () is a shallow copy that copies references to the Object’s attributes. Not the object itself. This method works for both arrays and objects.
(2) array.prototype. concat() and array.prototype. slice() array.prototype. concat() and array.prototype. slice() are both Array The method on the prototype only works for Array.
var arr1 = [1.3, {user: 'aaa'
}]
var arr2 = arr1.concat();
arr2[0] = '一';
arr2[2].user = 'AAA';
console.log('arr1',arr1)
console.log('arr2',arr2)
var arr1 = [1.3, {user: 'aaa'
}]
var arr2 = arr1.slice();
arr2[0] = '一';
arr2[2].user = 'AAA';
console.log('arr1',arr1)
console.log('arr2',arr2)
Copy the code
Note: Both the Slice and Contact methods of Array do not modify the Array. Instead, they return a new Array that makes a shallow copy of the original Array. Same as object.assign (), both methods copy the attributes of the first layer in sequence. If the attributes of the first layer are primitive data types, the values are copied. If it is a reference data type, the memory address is copied.
JS deep copy
Values of all referenced types in an object’s properties are iterated until values of the base type are iterated.
Parse (json.stringify ()) Converts an object to a string using json.stringify (), and parses a string to an object using json.parse ().
Var obj1 = {' name ':' zhangsan ', 'language' : [1, [2, 3], [4, 5]],}; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.name = "lisi"; Obj2. language[1] = [" 三","三"]; console.log('obj1',obj1) console.log('obj2',obj2)Copy the code
Disadvantages: This approach can do deep copies of arrays and objects and primitive data types, but not functions. Because the json.stringify () method is converting a javascript value to my JSON string, it cannot accept the function.
Other impacts:
- If there is a time object in the object, the time is a string instead of a time object in the copied object
- If there are RegExp, Error objects in the object, the serialized result is empty
- If the object has a function or undefined, the result of serialization will lose the function or undefined
- If the object has NAN, infinity, or -infinity, the serialized result becomes NULL
- Json.stringfy () serializes only the enumerable properties of the object, and if any of them are generated by the constructor, the constructor is discarded when copied
- Deep copy cannot be correctly implemented if there are circular references in the object