手写深拷贝

57 阅读1分钟
        function deepClone(target, set = new Set()) { // 这个给参数赋初始值实在巧妙,可以不用写闭包了
            if (!(target instanceof Object)) return target; // 基本类型直接返回原值
            const { constructor } = target // 解构赋值,遵循dry原则
            if (constructor === Function) return target // 没必要对函数深拷贝
            if (constructor === Map) {
                const result = new Map();
                for (let [key, value] of target) {
                    result.set(key, deepClone2(value)) // DFS
                }
                return result
            }
            if (constructor === Set) {
                const result = new Set();
                for (let item of target) {
                    result.add(deepClone2(item)) // DFS
                }
                return result
            }
            // 剩下 对象和数组类型了,其他类型如 Date 暂不考虑了,因为也不常见
            if (set.has(target)) return target // 第二轮发现如果还是自己,直接返回原值,解决循环引用
            set.add(target); // 解决循环引用
            const result = Array.isArray(target) ? [] : {};
            Reflect.ownKeys(target).forEach(key => { // Reflect.ownKeys()是我个人看来遍历对象的最优解
                result[key] = deepClone2(target[key], set) // DFS,没什么好说的
            })
            return result
        }