基础版(不能解决循环引用)
基础版
1 2 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; }
|
执行结果
1 2 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);
|
如果循环引用到导致爆栈
1 2 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);
|

增强版(兼容循环引用)
1 2 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; }
|
此时循环引用则正常输出
1 2 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
属性为一个循环嵌套属性;
