浅拷贝深拷贝递归

常见的基本数据类型:Number、String 、Boolean、Null和Undefined

引用数据类型:Object、Array、Function

1)基本数据类型:存储在栈内存中,可以直接访问到该变量的值。

2)引用数据类型:存储在堆内存中,每个堆内存对象都有对应的引用地址指向它,引用地址存放在栈中

浅拷贝 : 只是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据

深拷贝: 将数据中所有的数据拷贝下来,对拷贝之后的数据进行修改不会影响到原数据

深拷贝和浅拷贝是只针对引用数据类型(Object和Array)

拷贝等易于赋值 但是它又和赋值有着区别

先来看两个例子,对比赋值与浅拷贝会对原数据带来哪些改变

例1给对象赋值:原数据也会一起改变

      //给对象赋值
       var obj = {
          'name': '小红',
          'age': 16,
          'like': [1, [2, 3], [4, 5]],
        }
        var obj1 = obj
        obj1.name = "小明"
        obj1.like = ["篮球", "跳远"]
        console.log(obj, "obj");
        console.log(obj1, "obj1");

                               原数据以及原数据中包含的子对象都发生了改变 :

例2利用浅拷贝给对象赋值:原数据不会发生改变,但是给原数据中的子对象赋值的话会使原数据中的子对象发生改变

     //利用浅拷贝给对象赋值
        var obj = {
          'name': '小红',
          'age': 16,
          'like': [1, [2, 3], [4, 5]],//子对象
        }
        var obj1 = shallowCopy(obj)
        obj1.name = "小明"
        obj1.like[1] = ["篮球", "跳远"] //修改子对象
        function shallowCopy(src) {
          var str = {};
          for (var prop in src) {
            if (src.hasOwnProperty(prop)) {
              str[prop] = src[prop]
            }
          }
          return str
        }
        console.log(obj, "obj");
        console.log(obj1, "obj1");

                                         原数据不变,原数据中包含的子对象发生改变: 

 总结: 

 

浅拷贝的实现方式

1.Object.assign()

Object.assign() 是 Object 的一个方法

    var obj = {};
    var objass = {
      name: '小红',
      info: {
        age: 18
      }
    };
    Object.assign(obj, objass);//第一个参数obj是拷贝的目标对象,第二个参数objass是拷贝的来源对象
    obj.info.age = 28
    obj.name = "小明"
    console.log(objass,"原数据");
    console.log(obj,"浅拷贝后的数据");

                                原数据不变,原数据中包含的子对象改变:

2.Array.prototype.concat()

Array.prototype.concat()是数组的一个方法,使用场景比较少,使用concat连接一个含有引用类型的数组时,需要注意修改原数组中的元素的属性,因为它会影响拷贝之后连接的数组

        var arr = [1, 2, { name: '小红' }];
        var newArr = arr.concat();
        newArr[2].name = 'wy';
        console.log(arr);
        console.log(newArr);

                                       原数据不变,原数据中包含的子对象改变:

3.Array.prototype.slice()

Array.prototype.slice()是数组的一个方法,同cancat

        var arr = [1,3,{name:"小红"}]
        var str = arr.slice()
        str[2].name="小明"
        console.log(arr)

深拷贝的实现方式 

1.JSON.parse(JSON.stringify())

原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝 (针对对象和数组)

        var arr = [1,3,{name:"小红"}]
        var str =JSON.parse(JSON.stringify(arr))
        str[2].name="小明"
        console.log(arr,str)

                                        原数据以及原数据中包含的子对象都不会发生改变:

2.递归方法

原理:遍历对象和数组直到里边都是基本数据类型,然后再去复制

function deepClone1(obj) {
  //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
  var objClone = Array.isArray(obj) ? [] : {};
  var key = null
  if (obj && typeof obj === "object") {
    for (key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (obj[key] && typeof obj[key] === "object") {
          objClone[key] = deepClone1(obj[key]);
        } else {
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}
var arr = [1, 2, { name: "小红" }]
var str = deepClone1(arr)
str[2].name = "小明" //修改原数据中的子对象
console.log(arr, "原数据");
console.log(str, "通过递归深拷贝的数据");

                             原数据以及原数据中包含的子对象都不会发生改变: 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值