For deep copy, the concept of shallow copy is not much said, the concept can be Baidu yo! Here are some research on deep copy objects!
Only deep copy of value type data
For data objects with only values, the following line is enough!
JSON.parse(JSON.stringify(obj))
A simple, unstructured, deep copy
function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { if (typeof source[i] === 'object') { target[i] = clone(source[i]); // Pay attention here. } else { target[i] = source[i]; } } } return target; }
Problems:
- No inspection of parameters
- The logic of judging whether the object is not rigorous enough
- Array compatibility is not considered
Advanced deep copy
function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj) { let tempObj = Array.isArray(obj) ? [] :{}; for(let key in obj) { tempObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key]; } return tempObj; }
Problems:
- There is a problem with the copy ring, that is, the copy of the circular reference to the object
Deep copy for ring
You can use a WeakMap structure to store the copied object. When copying, you first query the WeakMap to see if the object has been copied. If it has been copied, take out the object and return it. Modify the deepCopy function as follows:
function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { if(hash.has(obj)) return hash.get(obj) let cloneObj = Array.isArray(obj) ? [] : {} hash.set(obj, cloneObj) for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj }
Problems:
- No consideration is given to the copy of new Date(), regular, function type objects
Combining ring, for deep copy of date,reg, arrow function type
const obj = { arr: [111, 222], obj: {key: 'object'}, a: () => {console.log('function')}, date: new Date(), reg: /regular/ig} function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { let cloneObj; let Constructor = obj.constructor; switch(Constructor){ case RegExp: cloneObj = new Constructor(obj) break; case Date: cloneObj = new Constructor(obj.getTime()) break; case Function: cloneObj = eval(obj.toString()); break; default: if(hash.has(obj)) return hash.get(obj) cloneObj = new Constructor() hash.set(obj, cloneObj) } for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj; } const cloneObj = deepCopy(obj); console.log(cloneObj);
For more legacy problems, copy functions. If function is not an arrow function, how to solve it? Also, do you want to copy the properties on the prototype chain? How to copy non enumeration properties? How to copy Error objects and so on?