You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
let a1 = 0; // 栈内存
let a2 = "this is string" // 栈内存
let a3 = null; // 栈内存
let b = { x: 10 }; // 变量 b 存在于栈中,{ x: 10 } 作为对象存在于堆中
let c = [1, 2, 3]; // 变量 c 存在于栈中,[1, 2, 3] 作为对象存在于堆中
当我们要访问堆内存中的引用数据类型时
从栈中获取该对象的地址引用
再从堆内存中取得我们需要的数据
基本类型发生复制
let a = 20;
let b = a;
b = 30;
console.log(a); // 20
前言
栈内存与堆内存 、浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然。
笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习。
栈
定义
栈
结构。栈顶
,另一端就叫栈底
。操作受限
的线性表,只允许在一端插入和删除数据。空栈
。栈也被用在编程语言的编译器和内存中保存变量、方法调用等,比如函数的调用栈。
堆
定义
它的存取数据的方式,与书架与书非常相似。我们不关心书的放置顺序是怎样的,只需知道书的名字就可以取出我们想要的书了。
好比在 JSON 格式的数据中,我们存储的 key-value 是可以无序的,只要知道 key,就能取出这个 key 对应的 value。
堆与栈比较
栈内存与堆内存
JavaScript 中的变量分为基本类型和引用类型。
基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问,并由系统自动分配和自动释放。
这样带来的好处就是,内存可以及时得到回收,相对于堆来说,更加容易管理内存空间。
JavaScript 中的
Boolean、Null、Undefined、Number、String、Symbol
都是基本类型。引用类型(如对象、数组、函数等)是保存在堆内存中的对象,值大小不固定,栈内存中存放的该对象的访问地址指向堆内存中的对象,JavaScript 不允许直接访问堆内存中的位置,因此操作对象时,实际操作对象的引用。
JavaScript 中的
Object、Array、Function、RegExp、Date
是引用类型。结合实例说明
当我们要访问堆内存中的引用数据类型时
基本类型发生复制
在栈内存中的数据发生复制行为时,系统会自动为新的变量分配一个新值,最后这些变量都是 相互独立,互不影响的。
引用类型发生复制
结合下图理解
总结
浅拷贝与深拷贝
上面讲的
引用类型的复制
就是浅拷贝,复制得到的访问地址都指向同一个内存空间
。所以修改了其中一个的值,另外一个也跟着改变了。深拷贝:复制得到的访问地址指向
不同的内存空间,互不相干
。所以修改其中一个值,另外一个不会改变。平时使用数组复制时,我们大多数会使用
=
,这只是浅拷贝,存在很多问题。比如:很明显,浅拷贝下,拷贝和被拷贝的数组会相互受到影响。
所以,必须要有一种不受影响的方法,那就是深拷贝。
深拷贝的的复制过程
数组
一、for 循环
二、slice 方法
三、concat 方法
四、es6 扩展运算
五、JSON.parse 与 JSON.stringify
注意:该方法在数据量比较大时,会有性能问题。
对象
一、对象的循环
二、JSON.parse 与 JSON.stringify
可实现多维对象的深拷贝。
注意:进行JSON.stringify() 序列化的过程中,undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。
三、es6 扩展运算
四、Object.assign()
Object.assign() 只能实现一维对象的深拷贝。
通用深拷贝方法
简单版
但上面的深拷贝方法遇到循环引用,会陷入一个循环的递归过程,从而导致爆栈,所以要避免。
结果如下:
总结:深刻理解 javascript 的深浅拷贝,可以灵活的运用数组与对象,并且可以避免很多 bug。
文章输出计划
JavaScript 数据结构与算法之美 的系列文章,坚持 3 - 7 天左右更新一篇,暂定计划如下表。
7. 最后
文章中的代码已经全部放在了我的 github 上,如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
关注我的公众号,第一时间接收最新的精彩博文。
文章可以转载,但须注明作者及出处,需要转载到公众号的,喊我加下白名单就行了。
参考文章:
JavaScript栈内存和堆内存
JavaScript实现浅拷贝与深拷贝的方法分析
浅拷贝与深拷贝(JavaScript)
The text was updated successfully, but these errors were encountered: