JavaScript ES6中的深拷贝和浅拷贝

今天在做Vue项目时,遇到了涉及到对象展开运算符"..."是深拷贝还是浅拷贝的问题,在问答里看到了这篇回答,由于无法转载,在这里记录一下。

先来了解下,浅拷贝和深拷贝各自的含义:

数据可以分为两大类:一类是基本数据,一类是引用数据;而数据存储位置又可分为栈和堆。

基本数据是存储在栈中的,深拷贝和浅拷贝操作的都是真实的数据,所以没有区别。

故而,深拷贝和浅拷贝主要是针对引用数据来说的

引用数据,相当于是在栈中存储了一个地址,这个地址指向堆中的真实数据,

浅拷贝,相当于把栈中的地址给了一个新的对象,新对象和旧对象指向的都是堆中同一个数据,所以无论哪个对象发生变化都会影响堆中的这个数据;

深拷贝,是在堆中重新开辟一片空间,生成了一个新的数据区域,这样新对象指向的是新的数据,旧对象指向的是旧的数据,所以这两个数据区无论谁发生变化都不会影响另一个。

浅拷贝

浅拷贝是指创建一个新的对象,把这个对象的原始属性精确拷贝一份,
如果是基本类型就拷贝基本类型的值
如果是引用类型,拷贝的就是内存地址,如果其中一个引用类型改变了值,那么就会影响另一个对象

深拷贝

深拷贝是将一个对象从内存中完成拷贝出来,在内存中开辟一个新的区域存放对象,并且两者不会相互影响

看图理解

在这里插入图片描述

在这里插入图片描述

例子

赋值

var person1 = {
  name: '小明',
  age: 18,
  sex: '男',
}

var xiaoHong = person1; // 这里只是将引用变量person1给了xiaoHong
xiaoHong.name = '小红';

console.log(person1) // 输出:{name: "小红", age: 18, sex: "男"}
console.log(xiaoHong)// 输出:{name: "小红", age: 18, sex: "男"}

由上面的例子,很清楚的看到:当xiaoHong的name属性值变化了之后,person1的name属性值也发生变化了,可以使用浅拷贝来解决这个问题

浅拷贝—对象展开运算符

var person1 = {
  name: '小明',
  age: 18,
  sex: '男',
}

var xiaoHong = {...person1}
xiaoHong.name = '小红';

console.log(person1) // 输出: {name: "小明", age: 18, sex: "男"}
console.log(xiaoHong)// 输出: {name: "小红", age: 18, sex: "男"}

哎,用对象展开符的xiaoHong的name属性变化了之后,person1的name属性没有变化呀!难道对象扩展符是深拷贝?别急,往下看。

再看下面的例子,对象中包含着第二层数据对象。

var person1 = {
  name: '小明',
  age: 18,
  sex: '男',
  hobby: {
    music: '伤感类歌曲',
    like: '吃饭、睡觉、打游戏',
  }
}

var xiaoHong = {...person1}
xiaoHong.name = '小红';
xiaoHong.hobby.music = '小清新歌曲';

console.log(person1)
// 输出: {name: "小明", age: 18, sex: "男", hobby: {music: "小清新歌曲",like: "吃饭、睡觉、打游戏"}}
console.log(xiaoHong)
// 输出: {name: "小红", age: 18, sex: "男", hobby: {music: "小清新歌曲",like: "吃饭、睡觉、打游戏"}}

看上面代码片段,对比新旧两个对象的输出:
在这里插入图片描述
你发现对象展开运算符并不是深拷贝,而是浅拷贝。

我感觉可以这么理解:
展开运算符使用的对象内部如果是基本数据类型,就是深拷贝;
展开运算符使用的对象内部如果是引用数据类型,那就是浅拷贝;

这种时候,就需要深拷贝解决问题了

深拷贝 — JSON.parse(JSON.stringify(object))

let obj = {
  a: 1,
  b: {
    c: 2,
    d: 3,
  },
}
obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值