深浅拷贝(也叫深浅复制)

深浅拷贝

一.概念

其实一般来说,我们遇到深浅拷贝的问题,都是针对引用数据类型的变量操作.先了解下数据类型
1.值类型和引用类型
值类型:直接存储其值,在内存中,是存在栈内存中引用类型: 存储对值的引用,在内存中,是存在堆内存中,变量本身仅仅是一个指向堆中的实际数据地址,存在栈内存中(说白了,就是引用数据类型,实际上存在堆内存中,杂乱无序的放着,但是会有一个指针,指向堆内存中的地址, 而这个指针则是在栈内存中存储)
1.1值类型
Boolean
String
Undefined
Null (typeof 去判断时,会是object,因为null被转换成机器语言时很多个0,而只要前三个为0的话,就会被机器语言判断为object)
Number
Symbol(ES6 唯一性)
1.2 引用类型
Object
Array
Function
RegExp
Date
Function

1.浅拷贝

浅拷贝拷贝的是对象的指针,没有新建空间地址,新老对象共用的同一份地址,指向对内存中同一个地方,修改原来的对象会影响新对象

var obj1={
    a:1
}

var obj2=obj1;

obj2.a=5;
console.log('obj1.a',obj1.a); //5
console.log('obj2.a',obj2.a); //5

上述代码,就是一个浅拷贝,对象通过等于号直接赋值,是一个浅拷贝,obj1对象赋值给了obj2,实际上obj2只是拷贝了obj1在内存中栈中的一个地址,也就是指针,他们俩会共同指向堆中数据

2.深拷贝

深拷贝会在内存中,开辟一个相同的空间地址,并且复制相同的数值,两者互不干扰

2.1JSON.parse+JSON.stringify

用JSON.stringify把对象转为字符串,再用JSON.parse把字符串转为新的对象.

      var obj3 = {
            classId: 2001,
            userinfo: {
                name: 'liuqiao',
                age: '27'
            }
        }

        var obj4 = JSON.parse(JSON.stringify(obj3));

        obj4.userinfo.name='zhangsan';
        console.log(obj3.userinfo.name); //liuqiao
        console.log(obj4.userinfo.name); //zhangsan
       

局限性:Number,String,Boolean,Array,可以转为JSON对象,但是function这种不行

2.2 lodash 实现深拷贝

lodash是一个高性能的 JavaScript 实用工具库,里面的lodash.cloneDeep()实现深拷贝,原理也是递归实现的

  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
  <script>
          var obj3 = {
            classId: 2001,
            userinfo: {
                name: 'liuqiao',
                age: '27'
            }
          }

		var obj4 = _.cloneDeep(obj3);
        obj4.userinfo.name = 'zhangsan';
        console.log(obj3.userinfo.name); //liuqiao
        console.log(obj4.userinfo.name); //zhangsan
  </script>
2.3Object.assign()

实际上Object.assign是一个浅拷贝,但是如果是数据结构只有一层,可以实现深拷贝

		var obj6={};
        var obj5={
            a:1
        }

        obj6= Object.assign(obj6);
        obj6.a=2;
        console.log(obj6.a); //2
        console.log(obj5.a); //1
        

Object.assign,如果数据结构有多层,则是浅拷贝

    	var obj3 = {
            classId: 2001,
            userinfo: {
                name: 'liuqiao',
                age: '27'
            }
        }		

		var obj4={};

        obj4= Object.assign({},obj3);
        obj4.userinfo.name = 'zhangsan';
        console.log(obj3.userinfo.name); //zhangsan
        console.log(obj4.userinfo.name); //zhangsan
2.5 ES6扩展运算符 …

与Object.assign() 一样,如果数据结构只有一层,是深拷贝,多层结构了是浅拷贝,只能拷贝第一层的
扩展运算符浅拷贝

  		 var obj3 = {
            classId: 2001,
            userinfo: {
                name: 'liuqiao',
                age: '27'
            }
        }

        obj4 = { ...obj3 }
        obj4.userinfo.name = 'zhangsan';
        obj4.classId=3004;
        console.log(obj3.userinfo.name); //zhangsan
        console.log(obj4.userinfo.name); //zhangsan
        console.log(obj3.classId); //2001
        console.log(obj4.classId); //3004

扩展运算符深拷贝

	   var obj6 = {};
        var obj5 = {
            a: 1
        }

        obj6 = { ...obj5 };
        obj6.a = 2;
        console.log(obj6.a); //2
        console.log(obj5.a); //1

二.总结
实际项目中,根据不同的业务场景,判断是否需要使用深拷贝,方式有很多种,根据需求来自己实现即可!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值