constgetType=obj=>Object.prototype.toString.call(obj);constisObject=(target)=>(typeoftarget==='object'||typeoftarget==='function')&&target!==null;constcanTraverse={'[objectMap]':true,'[objectSet]':true,'[objectArray]':true,'[objectObject]':true,'[objectArguments]':true,};constmapTag='[objectMap]';constsetTag='[objectSet]';constboolTag='[objectBoolean]';constnumberTag='[objectNumber]';conststringTag='[objectString]]';constsymbolTag='[objectSymbol]';constdateTag='[objectDate]';consterrorTag='[objectError]';constregexpTag='[objectRegExp]';constfuncTag='[objectFunction]]';consthandleRegExp=(target)=>{const{source,flags}=target;returnnewtarget.constructor(source,flags);}consthandleFunc=(func)=>{//箭头数直接返回自身if(!func.prototype)returnfunc;constbodyReg=/(?<={)(.|n)+(?=})/m;constparamReg=/(?<=().+(?=)s+{)/;ConstfuncString=func.toString();//分别匹配函数参数和函数体constparam=paramReg.exec(funcString);constbody=bodyReg.exec(funcString);如果(!正文)返回空;如果(参数){constparamArr=param[0].split(',');returnnewFunction(...paramArr,body[0]);}else{returnnewFunction(body[0]);}}consthandleNotTraverse=(target,tag)=>{constCtor=target.constructor;switch(tag){caseboolTag:返回新对象(Boolean.prototype.valueOf.call(target));casenumberTag:返回新对象(Number.prototype.valueOf.call(target));casestringTag:返回新对象(String.prototype.valueOf.call(target));casesymbolTag:returnnewObject(Symbol.prototype.valueOf.call(target));caseerrorTag:casedateTag:returnnewCtor(target);caseregexpTag:returnhandleRegExp(target);casefuncTag:returnhandleFunc(target);default:returnnewCtor(target);}}constdeepClone=(target,map=newWeakMap())=>{if(!isObject(target))返回目标;让类型=getType(目标);让克隆目标;if(!canTraverse[type]){//处理无法遍历的对象returnhandleNotTraverse(target,type);}else{//这波操作相当关键,可以保证对象的原型不丢失!让ctor=target.constructor;cloneTarget=newctor();}if(map.get(target))returntarget;map.set(target,true);if(type===mapTag){//处理Maptarget。forEach((item,key)=>{cloneTarget.set(deepClone(key,map),deepClone(item,map));})}if(type===setTag){//处理Settarget.forEach(item=>{cloneTarget.add(deepClone(item,map));})}//为(letpropintarget)处理数组和对象{if(target.hasOwnProperty(prop)){cloneTarget[prop]=deepClone(target[道具],地图);}}返回克隆目标;}
