SOURCE

// function deepClone(tree) {
//     const map = new WeakMap() // 方便内存释放
//     function deep(data) {
//         const obj = {}
//         const keys = [...Object.getOwnPropertyNames(data), ...Object.getOwnPropertySymbols(data)]
//         if (keys.length <= 0) return
//         const exist = map.get(data)
//         if (exist) return exist
//         map.set(data, obj)
//         keys.forEach(key => {
//             const item = data[key]
//             if(typeof item === 'object') {
//                 obj[key] = deep(data[key])
//             } else {
//                 obj[key] = data[key]
//             }
//         })
//         return obj
//     }   
//     return deep(tree)
// }






// function deepClone(tree) {
//     const map = new WeakMap()
//     function deep(data) {
//         const obj = {}
//         const keys = [...Object.getOwnPropertyNames(data), ...Object.getOwnPropertySymbols(data)]
//         if (keys.length <= 0) return
//         const exist = map.get(data)
//         if(exist) return exist // 防止循环引用
//         map.set(data, obj)
//         keys.forEach(key => {
//             const item = data[key]
//             if (typeof item === 'object') {
//                 obj[key] = deep(item)
//             } else {
//                 obj[key] = item
//             }
//         })
//         return obj
//     }
//     return deep(tree)
// }






function deepClone(data) {
    const map = new WeakMap(data)
    function deep(data) {
        const keys = [...Object.getOwnPropertyNames(data), ...Object.getOwnPropertySymbols(data)]
        if(!keys.length) return
        let obj = {}

        const exist = map.get(data)
        if(exist) return exist
        map.set(data, obj)
        keys.forEach(key => {
            if (typeof data[key] === 'object') {
                obj[key] = deep(data[key])
            } else {
                obj[key] = data[key]
            }
        })
        return obj
    }
    return deep(data) 
}































const field5 = {
    name: 'field5',
}
const target = {
    field1: 1,
    field2: undefined,
    field3: {
        child: 'child'
    },
    field4: [2, 4, 8],
    relative: field5
}
// 循环引用
field5['relative'] = target

const copyObj = deepClone(target)
console.log(copyObj)
console 命令行工具 X clear

                    
>
console