基础版(不能解决循环引用)
基础版
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | function deepClone(obj){
 if( obj == null ) return obj;
 if( obj instanceof Date ) return new Date(obj);
 if( obj instanceof RegExp ) return new RegExp(obj);
 if(typeof obj !== 'object') return obj;
 let cloneObj = new obj.constructor;
 
 for(let key in obj){
 if(obj.hasOwnProperty(key)){
 cloneObj[key] = deepClone(obj[key])
 }
 }
 return cloneObj;
 }
 
 | 
执行结果
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | let od = {name: '张三',
 age: 18,
 address: {
 province: '上海市',
 district: '浦东新区'
 },
 dateVal: dateVal: new Date('2020-02-14').toLocaleString(),
 re:new RegExp()
 }
 var cloneData = deepClone(od);
 console.log(cloneData);
 
 
 | 
如果循环引用到导致爆栈
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | let od = {
 name: '张三',
 age: 18,
 address: {
 province: '上海市',
 district: '浦东新区'
 },
 dateVal: dateVal: new Date('2020-02-14').toLocaleString(),
 re:new RegExp()
 }
 od.cloneSelf = cloneData
 var cloneData = deepClone(od);
 
 
 | 

增强版(兼容循环引用)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | function deepClone(obj,hash = new WeakMap()){
 
 if( obj == null ) return obj;
 if( obj instanceof Date ) return new Date(obj);
 if( obj instanceof RegExp ) return new RegExp(obj);
 if(typeof obj !== 'object') return obj;
 if(hash.has(obj)) return hash.get(obj);
 let cloneObj = new obj.constructor;
 
 hash.set(obj, cloneObj);
 
 
 for(let key in obj){
 if(obj.hasOwnProperty(key)){
 cloneObj[key] = deepClone(obj[key], hash)
 }
 }
 return cloneObj;
 }
 
 | 
此时循环引用则正常输出
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | let od = {
 name: '张三',
 age: 18,
 address: {
 province: '上海市',
 district: '浦东新区'
 },
 dateVal: dateVal: new Date('2020-02-14').toLocaleString(),
 re:new RegExp()
 }
 od.cloneSelf = cloneData
 var cloneData = deepClone(od);
 
 
 
 | 
cloneSelf 属性为一个循环嵌套属性;
