function deepCopy(data, hash=new WeakMap()){
if(typeof data !== 'object' || data == null){
return data;
}
if(hash.has(data)){
return hash.get(data);
}
const newData = Array.isArray(data) ? [] : {};
const dataKeys = Object.keys(data);
dataKeys.forEach(key => {
const current = data[key];
const typeString = Object.prototype.toString.call(current).toLowerCase();
if(typeof current !== 'object' || current == null){
newData[key] = current;
return;
}
switch(typeString){
case '[object array]':
newData[key] = [...deepCopy(current, hash)];
break;
case '[object set]':
newData[key] = new Set([...current.values()]);
break;
case '[object map]':
newData[key] = new Map([...current]);
break;
default:
hash.set(data, data);
newData[key] = deepCopy(current, hash);
}
})
return newData;
}