最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vue 项目开发中的对象拷贝

    正文概述 掘金(大冬冬)   2021-01-07   566

    在学习深拷贝之前,我们要先搞明白什么是深拷贝?

    在JS中,数据类型分为基本数据类型和引用数据类型两种,对于基本数据类型来说,它的值直接存储在栈内存中,而对于引用类型来说,它在栈内存中仅仅存储了一个引用,而真正的数据存储在堆内存中

    当我们对数据进行操作的时候,会发生两种情况

    一、基本数据类型

    var a = 3;
    var b = a;
    b = 5;
    console.log(a); // 3
    console.log(b); // 5
    

    可以看到的是对于基本类型来说,我们将一个基本类型的值赋予 a 变量,接着将 a 的值赋予变量 b ;然后我们修改 b ;可以看到 b 被修改了,而 a 的值没有被修改,两个变量都使用的是独立的数据

    二、引用数据类型

    var obj1 = {
        a:  1,
        b:  2,
        c:  3
    }
    var obj2 = obj1;
    obj2.a = 5;
    console.log(obj1.a);  // 5
    console.log(obj2.a);  // 5
    

    可以看到的是,两个对象的值全部被修改了 对象是引用类型的值,对于引用类型来说,我们将 obj1 赋予 obj2 的时候,我们其实仅仅只是将 obj1 存储在栈堆中的的引用赋予了 obj2 ,而两个对象此时指向的是在堆内存中的同一个数据,所以当我们修改任意一个值的时候,修改的都是堆内存中的数据,而不是引用,所以只要修改了,同样引用的对象的值也自然而然的发生了改变

    其实,上面的例子就是一个简单的浅拷贝,

    文章的主题,深拷贝!

    一、 浅拷贝

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

    二、深拷贝

    我们在实际的项目中,肯定不能让每个对象的值都指向同一个堆内存,这样的话不便于我们做操作,所以自然而然的诞生了深拷贝 深拷贝作用在引用类型上!例如:Object,Array 深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突

    三、深拷贝的实现

    1,首先看一下乞丐版的深拷贝吧!JSON.stringify()以及JSON.parse()

     var obj1 = {
        a: 1,
        b: 2,
        c: 3
    }
    var objString = JSON.stringify(obj1);
    var obj2 = JSON.parse(objString);
    obj2.a = 5;
    console.log(obj1.a);  // 1
    console.log(obj2.a); // 5
    

    可以看到没有发生引用问题,修改obj2的数据,并不会对obj1造成任何影响 但是为什么说它是乞丐版的呢? 那是因为 使用JSON.stringify()以及JSON.parse()它是不可以拷贝 undefined , function, RegExp 等等类型的

    2,接着来看第二种方式 Object.assign(target, source)

      var obj1 = {
        a: 1,
        b: 2,
        c: 3
    }
    var obj2 = Object.assign({}, obj1);
    obj2.b = 5;
    console.log(obj1.b); // 2
    console.log(obj2.b); // 5
    

    第二种方式实现的看起来也没有任何的问题,但是这是一层对象,如果是有多层嵌套呢

      var obj1 = {
        a: 1,
        b: 2,
        c: ['a','b','c']
    }
    var obj2 = Object.assign({}, obj1);
    obj2.c[1] = 5;
    console.log(obj1.c); // ["a", 5, "c"]
    console.log(obj2.c); // ["a", 5, "c"]
    

    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]))
                }
             // 判断如果当前的值是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 = {
            name: {
                c: /a/,
                d: undefined,
                b: null
            },
            ext: function () {
                console.log(this.a)
            },
            lab: [
                {
                    a: 'c',
                    b: /b/,
                    c: undefined
                },
                'a',
                3
            ]
        }
        let obj2 = deepClone(obj1);
            console.log(obj2);
    

    vue 项目开发中的对象拷贝 可以看到最终拷贝的结果是null、undefinde、function、RegExp等特殊的值也全部拷贝成功了,而且我们修改里边的值也不会有任何问题的 到这里我们就实现了一个简单的深拷贝,当然,我的这个也只是简单实现一下,还有很多问题没有解决

    神器都是在最后面的

    4,使用JSON方法将数据解析成字符串,之后再转换成JSON对象数据

           let obj1 = {
            name: {
                c: /a/,
                d: undefined,
                b: null
            },
            ext: function () {
                console.log(this.a)
            },
            lab: [
                {
                    a: 'c',
                    b: /b/,
                    c: undefined
                },
                'a',
                3
            ]
        }
        let obj2 = JSON.parse(JSON.stringify(obj1));
            console.log(obj2);
    

    vue 项目开发中的对象拷贝

    可以看到,方法拷贝不出,一些难解析的也解析不出,所以,这个方便快捷,需要注意 我通常使用该方法进行拷贝,一直踩坑


    起源地下载网 » vue 项目开发中的对象拷贝

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元