const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null);
const deepClone = function(obj,hash = new WeakMap()){
if(hash.has(obj)) return hash.get(obj);
let type = [Date,RegExp,Set,Map,WeakMap,WeakSet];
if(type.includes(obj.constructor)) return new obj.constructor(obj);
let allDesc = Object.getOwnPropertyDescriptors(obj);
let cloneObj = Object.create(Object.getPrototypeOf(obj),allDesc);
let symKeys = Object.getOwnPropertySymbols(obj);
if (symKeys.length > 0) {
symKeys.forEach(symKey => {
cloneObj[symKey] = isComplexDataType(obj[symKey]) ? deepClone(obj[symKey], hash) : obj[symKey]
})
}
hash.set(obj,cloneObj);
for(let key of Reflect.ownKeys(obj)){
cloneObj[key] =
(isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key],hash) : obj[key];
}
return cloneObj;
};
let obj = {
arr : [0,1,2,3,4,5,6]
};
let obj2 = deepClone(obj);
obj2.str = 'flten';
console.log(obj,obj2);
console.log('-------------');
let a = {
name: "lk",
course: {
vue: "Vue.js",
react: "React.js"
},
a1: undefined,
a2: null,
a3: 123,
a4: NaN
};
a.circleRef = a;
let b = deepClone(a);
console.log(b);