手写js深拷贝

124 阅读1分钟

众所周知,内存包含的结构中,有堆与栈。在JS里,字面量类型变量存放在栈中,储存的是它的值,而引用类型变量虽然在栈中也占有空间,但储存的只是一个内存地址(通过该地址可以索引找到真实结构所在的内存区域),它的真实结构是存在于堆中的。如果复制一个对象,复制出来的对象指向的还是被复制对象的地址,修改了复制出来的对象的属性,原对象也会被修改,所以就用到了深拷贝。

    /**
     * 深拷贝
     * @param {Object} obj是要拷贝的对象
     */
    function deepClone(obj = {}) {
        if (typeof obj != 'object' || obj == null) {
            //obj是null,或者obj不是对象或者数组直接返回
            return obj
        }

        let result;
        if (obj instanceof Array) { //判断obj是对象还是数组
            result = []
        } else {
            result = {}
        }

        for (let key in obj) {
            //保障key不是原型的属性
            if (obj.hasOwnProperty(key)) {
                //递归调用
                result[key] = deepClone(obj[key])
            }
        }

        return result;
    }

    let obj1 = {
        name: '张三',
        phone: '1125',
        adress: {
            city: 'beijing'
        },
        fn: () => {
            console.log(123)
        }
    }	

    let obj2 = deepClone(obj1)
    obj2.phone = '89757'
    obj2.adress.city = 'shanghai'
    console.log('obj2', obj2)
    console.log('obj1', obj1)