First of all, we must make it clear that JavaScript variables fall into one of two types:
- Basic types of
- undefined
- null
- number
- string
- boolean
- symbol
Basic variables are stored directly by value, stored in the stack memory of simple data segments, can be directly accessed.
- Reference type Object
Objects in the heap, variables hold a pointer to another location. When a value of a reference type (object, array, etc.) needs to be accessed, the address pointer to the object is first obtained from stack memory, and then the required data is obtained from heap memory.
A simple example
var a = 2;
var obj1 = {b:2};
var obj2 = obj1;
obj2.b = 3;
console.log(obj1.b); / / 3
console.log(obj2.b); / / 3
Copy the code
There are situations where we need to Copy all of the values contained in one object to another object. In this case, a simple assignment operation will only Copy the pointer, but the value in the heap will not change. Therefore, we come to the following conclusions:
What is a deep copy
A deep copy is a copy of an object in the heap.
A deep copy is to create a new memory address and copy each property of the original object into it one by one. Operations on the copy object and source object do not affect each other.
Implement shallow copy
There has always been a mistake in implementing a deep copy, which is to iterate over the k-V pairs of one object and copy each one to another.
But it’s wrong. This is a shallowCopy.
The reason is simple: when the value in the k-v pair is Object, copying the past is still copying the reference. Such as
let obj = {
a: 1,
b:{
c: 2,
d: 3
}
}
let obj2 = {}
for(letitem of Object.keys(obj)){ obj2[item] = obj[item] } obj2.b.d = 2; Obj.b.d // Now obj.b.d becomes 2Copy the code
Another point
Assign is also a shallowCopy
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
obj1.a = 1;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
obj2.a = 2;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
obj2.b.c = 3;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}
Copy the code
How to implement deep copy
- Method 1: Parse and Stringify (simplest) for JSON objects
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.b.c = 3;
console.log(obj2.b.c); // { a: 0 , b: { c: 3}};
console.log(obj1.b.c); // { a: 0 , b: { c: 0}};
Copy the code
This method can handle all data types that can be represented in JSON format, but it cannot copy functions, regular expressions, etc., inside the object, and it will lose all constructor (i.e., break the constructor chain).
- Method two: recursive shallow copy
As mentioned earlier, a shallow copy can only copy one layer of an object, so a deep copy can be achieved by recursing on the shallow copy.
function deepCopy (oldObj, newObj){
for(let key in oldObj){
if(typeofoldObj[key] ! ='object') {// is a direct copy of the basic type
newObj[key] = oldObj[key];
}else {
newObj[key] = oldObj[key].constructor == '[Function: Array]'? [] : {}; deepCopy(oldObj[key],newObj[key]) } } }Copy the code
Arguments.calle can implement recursion in anonymous functions, or deepCopy(oldObj[key],newObj[key]). The drawback of this method is that it can cause an infinite loop if the object to be copied and the original object reference each other. (If you recurse all the way down to Object, you will have an infinite loop.
. for(let key in oldObj){
if(newObj[key] === oldObj[key]){
continue; }... }...Copy the code
- Method three: borrow tool library
loadash
Loadash has a.clonedeep method to implement deep copies.
Usage:
obj2 = _.cloneDeep(obj1);
In conclusion:
- The basic type variable is stored in the stack memory area, stored in the heap memory object, the variable is a pointer.
- Direct traversal object – to – copy is
Shallow copy
(shallowCopy) - A deep copy is a copy of an object in the heap.
- Of course, deep copy takes up more memory. Therefore, you must perform different copy processing according to different scenarios.