深拷贝(递归法)

57 阅读1分钟
const deepClone = (a,cache) =>{
    // 没有缓存就创建
    if(!cache){
        cache = new Map()
    }
    if(a instanceof Object){
        // object
        // 有这个属性就返回
        if(cache.get(a)){
            return cache.get(a)
        }
        let result
        if(a instanceof Function){
            if(a.prototype){
                // 普通函数
                result = function(){
                    return a.apply(this,arguments)
                }
            }else{
                // 箭头函数
                result = (...args)=>{
                    return a.call(undefined,...args)
                }
            }
        }else if(a instanceof Array){
            // 数组
            result = []
        }else if(a instanceof Date){
            // 日期
            result = new Date(a - 0)
        }else if(a instanceof RegExp){
            // 正则
            result = new RegExp(a.source,a.flags)
        }else{
            // 不是上述几种的默认为普通对象
            result = {}
        }
        cache.set(a,result)
        for(let key in a){
            if(a.hasOwnProperty(key)){
                result[key] = deepClone(a[key],cache)
            }
        }
        return result
    }else{
        // string number boolean null undefined symbol bigint
        return a
    }
}

// 验证
const a = {
    number: 1,
    bool: false,
    str: 'hi',
    empty1: undefined,
    empty2: null,
    array: [
        { name: 'frank', age: 18 },
        { name: 'jacky', age: 19 },
    ],
    date: new Date(2000, 0, 1, 20, 30, 0),
    regex: /\.(j|t)sx/i,
    obj: { name: 'frank', age: 18 },
    f1: (a, b) => a + b,
    f2: function (a, b) {
        return a + b
    },
}
a.self = a
const b = deepClone(a)
console.log('b', b)
console.log('b.self === b ', b.self === b)
console.log('b.self = hi', b.self === 'hi')
console.log('a.self !== hi', a.self !== 'hi')