2-2、手写深拷贝

56 阅读1分钟
  • JSON.parse(JSON.stringify(obj))方法:不能存放函数、时间对象、正则...

// 
<script>
    const obj1 = {
        name: "张三",
        age: 18,
        address: {
            city: "北京",
        },
        hobby: ["台球", "篮球"],
    };
    

    // const obj2 = obj1;
    const obj2 = deepClone(obj1);
    obj2.address.city = "上海";
    console.log(obj1.address.city); //北京
    console.log(obj2.address.city); //上海

    function deepClone(obj) {
        return JSON.parse(JSON.stringify(obj));
    }
</script>

此方法的弊端

function deepClone(obj) {
    return JSON.parse(JSON.stringify(obj));
}

第一个的fn属性显示出来了,第二个里面的fn属性消失了

image.png

  • 递归(没有考虑循环引用)

//递归方法
<script>
    const obj1 = {
        name: "张三",
        age: 18,
        address: {
            city: "北京",
        },
        hobby: ["台球", "篮球"],
        fn: function () {
            console.log(123);
        }
    };

    const obj2 = deepClone(obj1);
    console.log(obj1);
    console.log(obj2);

    function deepClone(obj) {
        if (typeof obj !== "object" || obj == null) {
            return obj;
        }
        let res = obj instanceof Array ? [] : {};

        for (let key in obj) {
            res[key] = obj[key];
        }
        return res;
    }
</script>

image.png

如果将obj2.address.city改成“上海”

<script>
    const obj1 = {
        name: "张三",
        age: 18,
        address: {
            city: "北京",
        },
        hobby: ["台球", "篮球"],
        fn: function () {
            console.log(123);
        }
    };

    const obj2 = deepClone(obj1);
    obj2.age = 20;
    obj2.address.city = "上海";
    console.log(obj1);
    console.log(obj2);

    function deepClone(obj) {
        if (typeof obj !== "object" || obj == null) {
            return obj;
        }
        let res = obj instanceof Array ? [] : {};

        for (let key in obj) {
            res[key] = obj[key];
        }
        return res;
    }

</script>

obj1里面的city也会变成上海

image.png

把循环里面的obj[key]再套上deepClone()就正常了

//递归
function deepClone(obj) {
        if (typeof obj !== "object" || obj == null) {
            return obj;
        }
        let res = obj instanceof Array ? [] : {};

        for (let key in obj) {
            res[key] = deepClone(obj[key]);
        }
        return res;
    }

image.png

将递归函数更严谨一点

        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                res[key] = deepClone(obj[key]);
            }
        }
        return res;
    }
  • lodash.cloneDeep 推荐,工作中没必要重复造轮子