【JavaScript笔记 · 特殊篇】用堆栈的内存思想深度理解深拷贝 / 浅拷贝


在JS的引用数据类型中会存在这种深拷贝 / 浅拷贝的问题。接下来我就详细的通过代码堆栈图示的形式来解释这一组概念。

一. 浅拷贝

引用数据类型的变量中保存的是引用地址。变量的引用地址保存在栈区,真正的值保存在堆区。

var a = {name:"zevin",age:"21"};
var b = a;
b.age++;
console.log(a.age); //输出:22

在这里插入图片描述
比如上述代码:

  1. 先定义一个变量——对象a,a的引用地址保存在栈区,并且在堆区开辟了一片地址为B001的内存空间来存储真正的值;
  2. 正常将a赋值给b——由图可见,ab中存储的是同样的引用地址,都指向同一片内存空间;
  3. 变量b中的属性值age自增1;
  4. 输出a的属性值age的值22;

这种引用地址的拷贝就被称为浅拷贝,实际操作的是同一块内存地址。就好比同一套房子又配了一把钥匙一样。

二. 深拷贝【克隆】

var c = JSON.pasre(JSON.stringify(a));
console.log(c); //输出:{name:"zevin",age:"22"}
c.age++;
console.log(a.age); //输出:22
console.log(c.age); //输出:23

在这里插入图片描述
对应的深拷贝就是重新声明了一个对象cc的属性值和a一模一样,即重新开辟了一片地址为B002的内存空间,在栈区中c保存的即为B002引用地址。

上述代码块中改变c的age值,实际操作的是B002中的age值,而B001中的并未改变。

这种值的拷贝就被称为深拷贝,实际是又开辟了一片内存地址。就好比又买了一套相同户型的房子。


三. 拓展

1. 深拷贝的实现方法:

  1. 对象 --> json字符串 --> 对象:JSON.pasre(JSON.stringify(a))
  2. 调用es6中object对象的assign方法:(把a拷贝到一个空对象中)Object.assign({},a)
  3. lodash第三方库;

2. 基本数据类型都是值的拷贝,也就是深拷贝。

猜你喜欢

转载自blog.csdn.net/JZevin/article/details/107616552