JS深克隆和浅克隆

本文探讨JavaScript中的深克隆和浅克隆概念。深克隆创建了一个全新的对象,包括其内部引用类型的副本,不改变原始对象。浅克隆复制基本类型值,但对引用类型仅复制地址。直接赋值、for in循环、Object.assign()和Lodash的_.cloneDeep()等方法被用于演示和比较深浅克隆的效果。示例代码展示了各种方法下如何影响原始对象及其复杂数据类型的属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深克隆:如果属性是基本类型,克隆的就是基本类型的值;如果属性是内存地址(引用类型),比如数组或者类对象,深克隆会新建一个对象空间,然后克隆里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。

浅克隆:如果属性是基本类型,克隆的就是基本类型的值;如果属性是内存地址(引用类型),克隆的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。

直接赋值

直接赋值的话不管是复杂数据类型以及简单数据类型,操作数据时都会相互影响!

代码演示

    let obj = {
      uname: '张三',
      age: 18,
      hobby: ['篮球', '跑步']
    }
    let copyObj = {}
    // 直接赋值
    copyObj = obj
    console.log(copyObj)
打印copyObj如下

在这里插入图片描述

修改copyObj里面的元素并打印
 let obj = {
      uname: '张三',
      age: 18,
      hobby: ['篮球', '跑步']
    }
    let copyObj = {}
    // 直接赋值
    copyObj = obj
    console.log(copyObj)
    // 修改copyObj里面的元素
    copyObj.uname = '李四'
    console.log(obj)
    console.log(copyObj)

打印结果
可以看出修改完copyObj的元素后,obj的元素也变化了,相互影响,满足不了我们需求

浅克隆 利用for in 遍历以及 Object.assign({},obj )

浅拷贝在执行完毕后在处理简单数据类型时,使用没有问题,但是在处理复杂数据类型时,会给复杂数据类型的地址给克隆对象,在修改克隆出来对象里面的复杂数据对象的属性时,会连带着给克隆对象的一块修改

for in遍历obj,给copyObj赋值,然后修改copyObj对象下面的uname以及hobby
  let obj = {
    uname: '张三',
    age: 18,
    hobby: ['篮球', '跑步'],
    sayHi() {
      console.log('HI');
    }
  }
  let copyObj = {}
// for in遍历对象
  for (let key in obj) {
    //将obj[key]都赋值给copyObj[key]
    copyObj[key] = obj[key]
  }
  console.log(copyObj);
  // 修改copyObj里面的属性
  copyObj.hobby.push('唱歌')
  console.log(copyObj, obj);
代码运行后 copyObj修改复杂数据类型的数据影响了obj的数据,但是修改简单数据类型没有影响obj;

在这里插入图片描述

使用Object.assign({},obj)进行克隆

Object.assign({},obj)是将目标的属性和方法都赋值到一个目标对象中!如下就是将obj的属性和方法复制到一个空对象中并返回一个新的对象

  let obj = {
    uname: '张三',
    age: 18,
    hobby: ['篮球', '跑步'],
    sayHi() {
      console.log('HI');
    }
  }
  let copyObj = Object.assign({}, obj)
  console.log(copyObj);
  copyObj.uname = '李白'
  copyObj.hobby.push('唱歌')
  console.log(copyObj, obj);

同样和for in 的方法一样,实现对象的克隆,但是复杂数据类型也会有影响
在这里插入图片描述

深克隆 使用JSON.parse 和JSON.stringify 以及Lodash进行克隆
 // 深克隆
  let obj = {
    uname: '张三',
    age: 18,
    hobby: ['篮球', '跑步'],
    sayHi() {
      console.log('HI');
    }
  }
  let jsonStr = JSON.stringify(obj)
  let jsonObj = JSON.parse(jsonStr)
  jsonObj.uname = '李白'
  jsonObj.hobby.push('唱歌')
  console.log(jsonObj, obj);

使用JSON.parse 和JSON.stringify 进行克隆修改复杂数据以及简单数据对源对象不会有影响,但是这个会给源对象里面的函数丢失!
在这里插入图片描述

使用Lodash 进行克隆
  let obj = {
    uname: '张三',
    age: 18,
    hobby: ['篮球', '跑步'],
    sayHi() {
      console.log('HI');
    }
  }
  let copyObj = _.cloneDeep(obj);
  copyObj.uname = '李白'
  copyObj.hobby.push('唱歌')
  console.log(copyObj, obj);

在这里插入图片描述
使用Lodashi里面的克隆可以完美的解决上面的问题,也是我们在开发中经常使用的方法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值