如何实现我心目中完美深拷贝的算法?

摘要:要求: 1. 实现传入参数的深拷贝,并返回拷贝后的对象。 2. 要考虑到日期、正则等特殊类型,还有ES6的新数据类型。 3. 要考虑循环引用情况。 思路: 基础数据类型的深拷贝,只要考虑一下是对象还是数组,递归即可。完美深拷贝难点在循环引用
要求: 1. 实现传入参数的深拷贝,并返回拷贝后的对象。 2. 要考虑到日期、正则等特殊类型,还有ES6的新数据类型。 3. 要考虑循环引用情况。 思路: 基础数据类型的深拷贝,只要考虑一下是对象还是数组,递归即可。完美深拷贝难点在循环引用和特殊类型。 循环引用可以用一个Map解决。 特殊类型,万变逃不开它的构造函数,只要用构造函数初始化一个新对象,保证原型都是一样一样的。 特殊类型也可能有自定义属性,记得创建完跟普通类型一起扔进循环里递归。 还有es6新数据类型symbol,不能被普通枚举,要用自己的特殊方法getOwnPropertySymbols()。 代码: const deepCopy = (target, map=new Map()) => { // 基础类型直接返回 if (typeof target !== 'object' || target === null) return target; // 查询循环引用 if (map.has(target)) return map.get(target); // 创建待返回对象, 并保持原型一致 const res = new target.constructor(target); // 存map map.set(target, res); // 遍历属性并拷贝 const keys = Object.getOwnPropertyNames(target); const symbols = Object.getOwnPropertySymbols(target); [...keys, ...symbols].forEach(item => { res[item] = deepCopy(target[item]); }) return res; } // 测试 const o1 = { name: 'o', o: { name: o1.name, }, d: new Date(), q: [1,2], a: '11', f: function() {}, r: /\d+/ } o1.d.aaa = 1; console.log(o1); const o2 = deepCopy(o1); console.log(o2);