JavaScript 之 深拷贝

1.使用 JSON.parse(JSON.stringify(obj))

 var obj={
            a:1,
            b:2,
            c:undefined,
            d:function(){
                console.log("ddd")
            },
        }
        console.log("obj----------------",obj)
        let obj2=JSON.parse(JSON.stringify(obj))
        console.log("obj2---------------",obj2)

 

   这种方式不可以拷贝 undefined , function, RegExp 等等类型的,原理就是数据类型发生变化后 就和原数据无关了,数据类型变化本身就是在深拷贝了。

2.使用Object.assign(target, source);

        var obj={
            a:1,
            b:2,
            c:[1,2,3,4]
        }
        var obj2 = Object.assign({},obj)
        console.log("obj------------",obj)
        obj2.c[0]=99
        console.log("obj2-----------",obj2)

 

这种方式如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题,Object.assign方法用来将源对象 “obj” 的所有可枚举属性,复制到目标对象"{}"。它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。简单的来说就是把第二个对象里面的数据,拷贝到第一个空对象里面。

3.使用 递归拷贝

        // 定义一个深拷贝函数  接收目标target参数
        function deepClone(target) {
            let result;            // 定义一个变量
            if (typeof target === 'object') {             // 如果当前需要深拷贝的是一个对象的话
                if (Array.isArray(target)) {             // 如果是一个数组的话
                    result = []; // 将result赋值为一个数组,并且执行遍历
                    for (let i in target) {                      // 递归克隆数组中的每一项
                        result.push(deepClone(target[i]))
                    }

                } else if(target===null) {               // 判断如果当前的值是null的话;直接赋值为null
                    result = null; 
                } else if(target.constructor===RegExp){              // 判断如果当前的值是一个RegExp对象的话,直接赋值   
                    result = target;
                }else {                 // 否则是普通对象,直接for in循环,递归赋值对象的所有值
                    result = {};
                    for (let i in target) {
                        result[i] = deepClone(target[i]);
                    }
                }
            } else {              // 如果不是对象的话,就是基本数据类型,那么直接赋值
                result = target;
            }
            return result;            // 返回最终结果
        }
        var obj={
            a:1,
            b:null,
            c:function(){
                console.log("cccc")
            },
            d:/d/
        }
        var obj2=deepClone(obj)
        obj2.b={
            b1:111
        }
        obj2.a=undefined
        obj2.c=function(){
            console.log("这是新的CCCCC")
        }
        console.log("obj--------------",obj)
        console.log("obj2-------------",obj2)
        console.log("obj.c()----------",obj.c)
        console.log("obj2.c()---------",obj2.c)

可以看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的

 

posted @ 2021-05-07 21:02  伴月阁  阅读(194)  评论(0编辑  收藏  举报