directory
- Deep copy – cyclic reference treatment weakMap writing method I
- Deep copy – cyclic reference treatment weakMap writing method ii
- Recursion – there are problems with circular references
- Recursion – Solves circular references
I. Deep copy-cyclic reference treatment weakMap writing method 1
function deepCopy(obj) {
// Hash table to record the reference relation of all objects
let map = new WeakMap(a);function dp(obj) {
let result = null;
let keys = Object.keys(obj);
let key = null,
temp = null,
existobj = null;
existobj = map.get(obj);
// If the object is already logged, return it
if (existobj) {
return existobj;
}
result = {}
map.set(obj, result);
for (let i = 0, len = keys.length; i < len; i++) {
key = keys[i];
temp = obj[key];
if (temp && typeof temp === 'object') {
result[key] = dp(temp);
} else{ result[key] = temp; }}return result;
}
return dp(obj);
}
const obj1 = {
x: 1
}
// obj1.z = obj1;
const obj2 = {
x: 2
}
obj1.next = obj2;
obj2.next = obj1;
const obj3 = deepCopy(obj1);
console.log(obj3)
Copy the code
Deep copy-cyclic reference weakMap writing method ii
// Use the Map function
function deepCopy(obj,map = new Map(a)){
if (typeofobj ! ='object') return
var newObj = Array.isArray(obj)? [] : {}if(map.get(obj)){
return map.get(obj);
}
map.set(obj,newObj);
for(var key in obj){
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] == 'object') {
newObj[key] = deepCopy(obj[key],map);
} else{ newObj[key] = obj[key]; }}}return newObj;
}
const obj1 = {
x:1.y:2.d: {a:3.b:4
}
}
obj1.z = obj1;
const obj2 = deepCopy(obj1);
console.log(obj2)
/ / output node {x: 1, y: 2 d: 4} {3, a: b:, z: [Circular]}
// Console output {x: 1, y: 2, d: {... }, z: {... }}
Copy the code
Triple recursion – there are problems with circular references
The following methods cannot be handled correctly if there is a circular reference in the object
function deepCopy(obj) {
// Create a new object
let result = {}
let keys = Object.keys(obj),
key = null,
temp = null;
for (let i = 0; i < keys.length; i++) {
key = keys[i];
temp = obj[key];
// If the value of the field is also an object, the operation is recursive
if (temp && typeof temp === 'object') {
result[key] = deepCopy(temp);
} else {
// Otherwise assign directly to the new objectresult[key] = temp; }}return result;
}
const obj1 = {
x: {
m: 1
},
y: undefined.z: function add(z1, z2) {
return z1 + z2
},
a: Symbol("foo")};const obj2 = deepCopy1(obj1);
obj2.x.m = 2;
console.log(obj1); //{x: {m: 1}, y: undefined, z: ƒ, a: Symbol(foo)}
console.log(obj2); //{x: {m: 2}, y: undefined, z: ƒ, a: Symbol(foo)}
Copy the code
Quad recursion – Solves circular references
1) Parent reference
A parent reference is a reference to a property of an object, which is the object itself. If we were to make a deep copy, it would be in the child element -> parent object -> child element… This loop continues, causing stack overflow. Take this example:
const obj1 = {
x: 1.y: 2
};
obj1.z = obj1;
constobj2 = deepCopy1(obj1); \ \ stack overflowCopy the code
The deepCopy function can be modified by simply checking whether an object’s fields reference the object or any parent of the object:
function deepCopy2(obj, parent=null) {
// Create a new object
let result = {};
let keys = Object.keys(obj),
key = null,
temp = null,
_parent = parent;
// If the field has a parent, you need to trace the parent of the field
while(_parent) {
// If the field references its parent, it is a circular reference
if(_parent.originParent === obj) {
// A circular reference returns a new object of the same class
return _parent.currentParent;
}
_parent = _parent.parent
}
for(let i=0,len=keys.length; i<len; i++) { key = keys[i] temp = obj[key]// If the value of the field is also a new object
if(temp && typeof temp === 'object') {
result[key] = deepCopy2(temp, {
// Perform deep copy recursively, passing the peer object to be copied and the new object to parent, facilitating the traceability of circular references
originParent: obj,
currentParent: result,
parent: parent
});
} else{ result[key] = temp; }}return result;
}
const obj1 = {
x:1
}
obj1.z = obj1;
const obj2 = deepCopy2(obj1);
Copy the code
2) Peer references
Test cases to be supplemented:
Copy the code
Solution: A parent reference is A reference, and A non-parent reference is A reference, so just record all objects in object A and match them to the newly created object.
reference
- Deep copy
- Deep copy – by me