简单理解深拷贝与浅拷贝

面试开发都会遇到的问题。咱就做个笔记记一下吧,嘿嘿。

浅拷贝

先看代码和打印结果

    let aaa = {a:1,b:2};
    let bbb = aaa;
    console.log(aaa===bbb)
    bbb.b = 3;
    console.log(aaa)
    console.log(bbb)

打印结果
打印结果
可以看出来,当我们改变bbb.b的值,aaa.b的值也发生了改变。这是为什么呢?因为当我们进行赋值操作时,只是将aaa在栈中存放的数据地址给复制了过来,所以aaa和bbb其实是指向的堆中的同一个对象。当aaa和bbb两者任一发生了改变,两者都会发生变化。

深拷贝

来,上代码

let obj = {
  a: '1',
  b: 666,
  c: [
      {ca1: 666,ca2: '999'},
      {cb1: ['a', 1, 'b', 2],cb2: [{cba1: '999',cba2: 666}]},
      [1, 2, 3]
  ]
}

function deepCopy(obj) {
  let result = Array.isArray(obj) ? [] : {}; //判断拷贝对象数据类型为Object还是Array
  for (item in obj) {
    if (typeof obj[item] === 'object') { //如果obj内元素typeof返回值为'object',则递归调用deepCopy进行循环拷贝(数组和对象的typeof返回值都是'object')
      result[item] = deepCopy(obj[item]) //递归
    } else {
      result[item] = obj[item] //直接赋值
    }
  }
  return result
}
let result = deepCopy(obj);
console.log(result == obj) //false
obj.c[0].ca2 = '666' //改变obj
obj.c[1].cb2 = '666' //改变obj
console.log(result) //result不随着改变
console.log(obj) //obj改变了

打印结果
打印结果
看起来有点眼花,哈哈哈,重点看改变的值,obj.c[0].ca2obj.c[1].cb2。可以看出来,深拷贝中,obj===result打印的是false。因为深拷贝是直接复制堆中的数据对象,所以现在obj和result在堆中是两个不相干的数据对象。所以在代码中,当我们改变了obj中的ca2和cb2,result也不会发生变化。

深拷贝的方法有很多,但我感觉原生这种是最适用的,它可以提取出来作为一个公共方法使用。当然,JSON.parse(JSON.stringify())和lodash库中也都可以实现相应的深拷贝。

总结

深拷贝和浅拷贝的区别就是在于,浅拷贝是去复制存在于栈中的地址指向,所以新的变量和其都指向堆中的同一个数据对象。而深拷贝是直接在堆中复制出来一个新的数据对象,一份变成了两份,两者毫不相干。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值