ES6中深拷贝/浅拷贝

ES6中深拷贝/浅拷贝的问题

浅拷贝

实现深浅拷贝的时候涉及到js中的数据类型
数据类型分为两种:
基本数据类型:存放在栈中(null,Number,String,undefined,Boolean)
引用数据类型:在栈中存放这个数据的地址,然后这个地址指向堆中的对象 object(object,function,array)

浅拷贝:浅拷贝的时候,他创建一个新的对象,这个对象中存放着原对象精准的值,如果对象是基本数据类型,拷贝的就是基本类型的值,如果对象是引用数据类型,拷贝的则是这个对象所指向的一个指针,如果其中一个对象的引用数据类型改变了值,那么会影响另外一个的值,简单来说就是,只拷贝第一层中的值,但是对象中的子对象不会,两者就会有相同的引用

数组中:可以实现浅拷贝的方法:扩展运算符,concat,slice
对象中:可以实现浅拷贝的方法:Object.assign()

let arr1 = [1,2,3,[1,2,3]];
let arr2 = arr1.slice();
console.log(arr1,arr2)//(4) [1, 2, 3, Array(3)] (4) [1, 2, 3, Array(3)]
arr2[0] = "hello"
console.log(arr1,arr2)//[1, 2, 3, Array(3)] (4) ["hello", 2, 3, Array(3)]
//--------------------------------
arr2[3][0] = "Hi"//都发生改变
console.log(arr1,arr2)

在这里插入图片描述
上述例子可以看到,第一层中的数据可以实现拷贝值,但是对于第二层中的引用类型就拷贝的不是值

深拷贝

深拷贝:就是创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”,两者之间改变互不影响,简单来说深拷贝就是,不仅拷贝了值,也将值对应的地址也复制过来,形成一个全新的内容,即使改变原对象的内容,也不会影响另一个
实现深拷贝的方法有两种:

  1. JSON.parse(JSON.stringify(obj));这种方式实现起来简单,就是先将obj使用JSON.stringify()方法转化为字符串,然后在将这个转化的字符串在进行转化JSON.parse(),这样转化过一次后,就产生了新的栈
    同样实现起来简单但是会有不足之处
    undefined/function/Symbol("foo") 这三种会在拷贝丢掉
  2. 使用递归
    对于上述的解决方法只能使用递归的解决,递归就是本身在继续调用本身,一层一层进行循环调用,但是要判断是基本数据类型还引用数据类型,如果是基本数据类型只需要直接拷贝基本类型的值就可以了,如果是引用数据,那就要继续调用本身的函数,来继续寻找引用数据类型中的基本数据,逐层查找直到最后
let obj = {
   a: undefined,
   b: function () {},
   c: Symbol("foo"),
   d: null,
   e: "hello",
   arr: [{
           uname: "lili",
           arr2: [1, 2, 3]
       },
       [1, 2, 3]
   ]
}
function deepCopy(obj, type = {}) {//type设置一个默认的空对象
   for (const key in obj) {//遍历obj中的属性
   // obj[key]表示对应属性名的属性,判断一下这个属性是基本数据还是引用数据
       if (typeof obj[key] === "object") {
       //type[key] 判断一下这个属性是数组还是对象,对应的创建一个空数组或者对象
           type[key] = Array.isArray(obj[key]) ? [] : {};
           //如果是hi引用数据类型就继续调用本身查找里面的属性
           deepCopy(obj[key], type[key])
       } else {
       //如果是基本数据就直接拷贝出属性对应的值放在type
           type[key] = obj[key];
       }
   }
   return type;//最后返回这个type对象
}

let x = new deepCopy(obj);//传递obj对象
x.arr[1][0] = "hi";//改变深层中的内容会发现对另外一个没有影响
console.log(x,obj);

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值