深拷贝与浅拷贝详解(包含ES6的内容)

在进入深拷贝和浅拷贝之前先了解一下js中的数据类型

基本数据类型:number、string、boolean、null、undefined
引用数据类型:object、function、array

我们先来看一下简单数据类型的复制

简单数据类型:将a的数据赋值给b,这样是没有问题的。

  <script>
            var a = 1;
            var b = a; // 栈内存会开辟一个新的内存空间,此时b和a都是相互独立的
  </script>

再来看一下引用数据类型的复制

引用数据类型不能通过简单赋值而进行复制,因为这样的话两者是存在关联的,改一个的数据另一个的数据也会跟着改变。

  <script>
            var obj1 = { a: 1, b: 2 };
            var obj2 = obj1;  // 赋值的内存地址,两者存在关联关系
  </script>

浅拷贝(对象/数组):假设B复制了A,当修改A时,如果B也跟着变了,说明这是浅拷贝。本质上,拷贝的是指针(内存)地址。

浅拷贝:适应于简单数据类型。对于复合数据类型(对象/数组),只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

介绍完浅拷贝概念了,对于简单类型的复制我们大家并不陌生,直接赋值就可以了,但是引用类型的呢?我们来看有这几种方法。

 1.使用Object.assign()   用于对象

         var person2 =  Object.assign({}, person1);
  • 无法应用于数组

  • 这种方式是浅拷贝的,无法拷贝嵌套对象、嵌套数组

2.JS中拷贝Array的slice和concat方法 用于数组

<script>
let arr = [1, 2, 3, 4];
let new_arr = arr.slice()
</script>

这里只介绍一个slice方法concat方法类似

3.for in 循环浅拷贝    用于对象/数组

 <script>
            // 适合浅拷贝
            var point1 = { x: 0, y: 0 }
            // 浅拷贝--es5版
            function shallow_copy(obj) {
                var copy = {};
                for (let key in obj) {
                    copy[key] = obj[key];
                }
                return copy;
            }
            var point2 = shallow_copy(point1);
 </script>

4.使用扩展运算符 用于对象/数组

            var person3 = { ...person1 };
  • 这种方式是浅拷贝的,无法拷贝嵌套对象、嵌套数组

深拷贝:假设B复制了A,当修改A时,如果B没有发生变化,说明这是深拷贝。本质上拷贝的是数据,在内存中重新生成的一份数据。

废话不多说 上代码

1.深拷贝实现方式:JSON方法

<script>
            var person6 = {
                name: "黄小米",
                age: 25,
                salary: undefined,
                tel: /^1[34789]\d{9}$/,
                school: {
                    name: '泰山学院',
                    location: '泰安'
                },
                sleep: function () {
                    console.log('zzz....')
                }
            }

            var person8 = JSON.parse(JSON.stringify(person6));
</script>
  • 这种方式无法拷贝 正则表达式、undefined,function

2.深拷贝实现方式:递归方法

这里就需要自己动脑子写一个了 hh

//使用递归的方式实现数组、对象的深拷贝
  function deepClone(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
  var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是数组
        if (obj && typeof obj === "object") {
            for (key in obj) {
               if (obj.hasOwnProperty(key)) {
                     // 判断是否嵌套对象 判断是否为正则表达式
                     if (obj[key] && typeof obj[key] === "object" && !(obj[key] instanceof RegExp)) {
                                objClone[key] = deepClone(obj[key]);
                            } else {
       //函数走这里,因为赋值的不是函数名,而是函数体,所以是深拷贝。和以前函数之间没有联系了!
                                objClone[key] = obj[key];
                            }
                        }
                    }
                }
                return objClone;
            }

            var person9 = deepClone(person6);

这样就实现了深拷贝😎

好了本篇文章就到这里了,喜欢的话可以关注我,会持续更新的,有错误欢迎大佬指出,大家也可以在我这里互相讨论学习,一起进步。

青山不改 绿水长流 下篇文章见

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值