What are deep and shallow copies?
Deep and shallow copies are for reference types (Array, Object) :
Shallow copy
Shallow copy is when two objects point to the same memory address, and changes in one affect the other
It’s just like building A, which is also called B, so building A and building B are actually the same building, because they have the same address. If this building is rebuilt, then both building A and Building B will change
Deep copy
Deep copy refers to a new object pointing to a new memory address. The change of two objects does not affect each other
It is just like building an identical building B in addition to building A, but the two buildings have different addresses. Of course, if building A is rebuilt, building B will not change
Object Common method of shallow copy
1. Simple assignment
var arr1 = [1.2.3];
var arr2 = arr1;
arr1[0] = 5;
console.log(arr1); // [5, 2, 3]
console.log(arr2); // [5, 2, 3]
console.log(arr1 === arr2); // true
Copy the code
2. The method of traversing the original object copy (the first layer is deep copy, the second layer is object/array is shallow copy)
If obj2 copies obj from obj1, it will be a shallow copy
var obj1 = { a: {a: "hello"}, b: 20};
var obj2 = {};
var arr = Object.entries(obj1)
for(let i=0; i<arr.length; i++){Object.defineProperty(obj2,arr[i][0] and {configurable: true.enumerable: true.writable: true.// The default value for all three is false, so it must be set to true
value: arr[i][1]
})
}
obj2.b = 100;
console.log(obj1); // { a: 10, b: 20}
console.log(obj2); // { a: 10, b: 100};
console.log(obj1 === obj2); // false
console.log(obj1.a === obj2.a); // true
Copy the code
3. Object.assign({}, obj) (layer 1 deep copy, layer 2 shallow copy Object/array)
var obj1 = { a: {a: "hello"}, b: 33 };
var obj2 = Object.assign({}, obj1);
obj2.a.a = "hello world";
console.log(obj1); // { a: {a: "hello world"}, b: 33 };
console.log(obj2); // { a: {a: "hello world"}, b: 33 };
console.log(obj1 === obj2); // false, the first layer is deep copy
console.log(obj1.a === obj2.a); // true, the second layer is a shallow copy if it is still an object
Copy the code
4. Object.fromentires (object.entires (obj))
var obj1 = { a: {a: "hello"}, b: 33 };
var obj2 = Object.fromEntires(Object.entires( obj1 ));
obj2.a.a = "hello world";
console.log(obj1); // { a: {a: "hello world"}, b: 33 };
console.log(obj2); // { a: {a: "hello world"}, b: 33 };
console.log(obj1 === obj2); // false, the first layer is deep copy
console.log(obj1.a === obj2.a); // true, the second layer is a shallow copy if it is still an object
Copy the code
In most practical cases we consider using deep copies, but we should be aware that if we inadvertently use shallow copies, tampering with other objects/arrays will occur. Of course, sometimes we will use shallow copies, such as public objects and so on
Object Common method of deep copy
1. obj2 = JSON.parse(JSON.stringify(obj1))
var obj1 = { a: {a: "hello"}, b: 33 };
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.b = "hello world";
console.log(obj1); // { a: "hello", b: 33 };
console.log(obj2); // { a: "hello world", b: 33};
console.log(obj1 === obj2); // false
Copy the code
Disadvantages:
- Unable to copy properties of a function type
- Objects will be discarded
constructor
Property, that is, there is no way to trace the original constructor
2. Recursive copy
An empty array [] or an empty object {} is generated in the middle of the address
function deepClone(obj1){
if(typeofobj1 ! = ="object") return; // (because of recursion) check whether it is a reference type first
let obj2 = obj1 instanceof Array ? [] : {}; // Check whether it is an array or an object
for(let key in obj1){
if(obj.hasOwnProperty(key)){ // copy the properties of the original object obj
obj2[key] = typeof obj1[key] === "object"? deepClone(obj1[key]) : obj1[key]; }}return obj2;
}
Copy the code
Testing:
let obj1 = {a: 11.b: function(){}, c: {d: 22}};
let obj2 = deepClone(obj1); // {a: 11, b: f(), c: {d: 22}};
obj1 === obj2 // false
Copy the code
An Array of shallow copy
1. Direct assignment
var arr1 = [1.2.3]
var arr2 = arr1
arr2[0] = 4
console.log(arr1) / / (4, 2, 3)
console.log(arr2) / / (4, 2, 3)
console.log(arr1 === arr2) // true
Copy the code
2. Arr2 = arr1.slice(0)
var arr1 = [1.2, {name: "Jack"}]
var arr2 = arr1.slice(0)
console.log(arr1 === arr2) // false
console.log(arr1[2] === arr2[2]) // true
Copy the code
3. Arr2 = []. Concat (arr1)
var arr1 = [1.2[4.5.6]]
var arr2 = [].concat(arr1)
console.log(arr1 === arr2) // false
console.log(arr1[2] === arr2[2]) // true
Copy the code
4. Arr2 = array. from(arr1)
var arr1 = [1.2[4.5.6]]
var arr2 = Array.from(arr1)
console.log(arr1 === arr2) // false
console.log(arr1[2] === arr2[2]) // true
Copy the code
Array deep copy
1. arrr2 = JSON.parse(JSON.stringify(arr1))
var arr1 = [1.2[4.5.6]]
var arr2 = JSON.parse(JSON.stringify(arr1))
console.log(arr1 === arr2) // false
console.log(arr1[2] === arr2[2]) // false
Copy the code
2. Recursive copy
With the method of deepClone
Refer to the article
- This article thoroughly understands deep and shallow copies of JavaScript
- Deep copy of an array in javascript