js深拷贝、深克隆

js深拷贝

上篇文章,我们看到的其实就是简单的浅拷贝。

一、 浅拷贝

对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,因为它们公用一条数据

二、深拷贝

在实际的项目中,不能让每个对象的值都指向同一个堆内存,不便于我们做数据的操作,所以我们需要用到深拷贝。

如下列方法:

方法一:JSON.stringify()、JSON。parse()在这里插入图片描述
没有发生引用问题,修改newObj的数据,并不会对obj造成数据改变。

我们还可以这样来用:
在这里插入图片描述

注意:使用JSON.stringify()、JSON.parse()它是不可以拷贝 undefined,function, RegExp 等等类型的

方法二: Object.assign(target, source)
在这里插入图片描述
这种方法看起来也没有任何的问题,但是这只是一层对象,如果是有多层嵌套呢?
在这里插入图片描述
我们来试下
在这里插入图片描述
可以看到对于一层对象来说是没有任何问题的,但是如果对象的属性对应的是其它的引用类型的话,还是只拷贝了引用,修改的话还是会有问题

方法三:递归拷贝

// 定义一个深拷贝函数  接收目标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]))
            }
         // 判断如果当前的值是null的话;直接赋值为null
        } else if(target===null) {
    
    
            result = null;
         // 判断如果当前的值是一个RegExp对象的话,直接赋值    
        } else if(target.constructor===RegExp){
    
    
            result = target;
        }else {
    
    
         // 否则是普通对象,直接for in循环,递归赋值对象的所有值
            result = {
    
    };
            for (let i in target) {
    
    
                result[i] = deepClone(target[i]);
            }
        }
     // 如果不是对象的话,就是基本数据类型,那么直接赋值
    } else {
    
    
        result = target;
    }
     // 返回最终结果
    return result;
}

效果:

 let obj1 = {
    
    
        a: {
    
    
            c: /a/,
            d: undefined,
            b: null
        },
        b: function () {
    
    
            console.log(this.a)
        },
        c: [
            {
    
    
                a: 'c',
                b: /b/,
                c: undefined
            },
            'a',
            3
        ]
    }
    let obj2 = deepClone(obj1);
        console.log(obj2);

在这里插入图片描述

看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的
到这里我们就实现了一个简单的深拷贝。

猜你喜欢

转载自blog.csdn.net/weixin_52400118/article/details/112826596