const _completeDeepClone = (obj, map = new Map()) => {
if(obj===null || typeof obj!=='object')return obj;
if(map.has(obj))return map.get(obj);
if(obj instanceof RegExp)return new RegExp(obj);
if(obj instanceof Date)return new Date(obj);
if(typeof obj==='function')return obj;
//处理普通数组
if(Array.isArray(obj)){
const objArray=[];
map.set(obj,objArray);
for(let i=0;i<obj.length;i++){
objArray[i]=_completeDeepClone(obj[i],map);
}
return objArray;
}
const copyobj={};
map.set(obj,copyobj)
for(const key in obj){
if(obj.hasOwnProperty(key)){
copyobj[key]=_completeDeepClone(obj[key],map);
}
}
return copyobj;
}
深拷贝函数详解:(要用递归)
设置map或者weakmap是为了解决循环引用问题。
首先第一个判断就是obj是否为空(null)或者obj不是对象(object)都直接返回本身
然后就是看map中有没有(has()),map中已经有了就直接返回mao中的(get())。
接下来有两个判断,一个是Date类型,另一个是RegExp类型,都是object+,所以直接new一个新的返回即可。
之后就是需要递归解决的数组和对象深拷贝。
用Array.isArray(),最稳妥的方法判断数组,如果是数组就创建一个新数组存结果,然后返回这个新数组。这个值需要被记录在map里面
objArray[i]=_completeDeepClone(obj[i],map),数组的每一位用递归调用解决。
对象深拷贝:
创建新对象,返回这个对象,也是需要记录在map里。
用for(const key in obj)逐个遍历塞入新对象,copyobj[key]=_completeDeepClone(obj[key],map),递归调用塞入新对象。
判断hasOwnProperty()这个不一定需要。



京公网安备 11010502036488号