let getEmpty = function (origin) { if(Object.prototype.toString.call(origin) === '[object Object]'){ return {}; } if(Object.prototype.toString.call(origin) === '[object Array]'){ return []; }
return origin;};
function deepCopyBFS(origin){ let queue = []; let map = new Map(); let target = getEmpty(origin); if(target !== origin){ queue.push([origin,target]); map.set(origin,target); }
while (queue.length) { let [ori,tar] = queue.shift(); for(let key in ori){ if(map.get(ori[key])){ tar[key] = map.get(tar[key]); continue; }
tar[key] = getEmpty(ori[key]); if(tar[key] !== ori[key]){ queue.push([ori[key],tar[key]]); map.set(ori[key],tar[key]); } } }
return target;}
function deepCopyDFS(origin){ let stack = []; let map = new Map(); let target = getEmpty(origin); if(target !== origin){ stack.push([origin,target]); map.set(origin,target); }
while (stack.length) { let [ori,tar] = stack.pop(); for(let key in ori){ if(map.get(ori[key])){ tar[key] = map.get(tar[key]); continue; }
tar[key] = getEmpty(ori[key]); if(tar[key] !== ori[key]){ stack.push([ori[key],tar[key]]); map.set(ori[key],tar[key]); } } }
return target;}
[deepCopyBFS, deepCopyDFS].forEach(deepCopy=>{ console.log(deepCopy({a:1})); console.log(deepCopy([1,2,{a:[3,4]}])) console.log(deepCopy(function(){return 1;})) console.log(deepCopy({ x:function(){ return "x"; }, val:3, arr: [ 1, {test:1} ] }))
let circle = {}; circle.child = circle; console.log(deepCopy(circle));})