写一个我心目中的完美深拷贝

要求:

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);

 

posted @ 2023-03-09 13:47  有洸  阅读(62)  评论(0)    收藏  举报