JS中栈和堆的区别?

目录

一、js的数据类型

二、什么是堆什么是栈

三、堆和栈的区别

四、总结

五、堆和栈的溢出


堆和栈是数据存储的一种结构

一、js的数据类型

为了更好容易的理解堆和栈,首先来复习一下js中的数据类型。在js中数据类型主要分为以下两大类:

基本类型: String,Number,Boolean,Null,Undefined,这5种基本数据类型它们是直接按值存放的,所以可以直接访问。
引用类型: Function,Array,Object,当我们需要访问这三种引用类型的值时,首先得从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。


 

二、什么是堆什么是栈

其实了解过一些数据结构的同学应该都对堆和栈有一定的认识,堆栈不仅仅只有js中才有这个概念,不过这篇文章只针对js来进行描述。

栈(stack): 由操作系统自动分配内存空间,自动释放,存储的是基础变量以及一些对象的引用变量,占据固定大小的空间。
堆(heap): 由操作系统动态分配的内存,大小不定也不会自动释放,一般由程序员分配释放,也可由垃圾回收机制回收。

三、堆和栈的区别

1、栈:基础变量的值是存储在栈中,而引用变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。(线性结构,后进先出)

优点:
(1)栈中的内容是操作系统自动创建、自动回收,占据固定大小的空间,因此内存可以及时得到回收,相对于堆来说,更加容易管理内存空间。
(2)相比于堆来说存取速度会快,并且栈内存中的数据是可以共享的,例如同时声明了var a = 1和var b =1,会先处理a,然后在栈中查找有没有值为1的地址,如果没有就开辟一个值为1的地址,然后a指向这个地址,当处理b时,因为值为1的地址已经开辟好了,所以b也会同样指向同一个地址。
缺点:
相比于堆来说的缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

 2、堆:堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能会被其他引用变量所引用(参数传递)。创建对象是为了反复利用(因为对象的创建成本通常较大),这个对象将被保存到运行时数据区(也就是堆内存)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

优点:
(1) 堆是操作系统动态分配的大小不定的内存,因此方便存储和开辟内存空间。
(2)堆中保存的对象不会自动释放,一般由程序员分配释放,也可由垃圾回收机制回收,因此生存周期比较灵活。
缺点:
相比于栈来说的缺点是,存在堆中的数据大小与生存期是不确定的,比较混乱,杂乱无章。

四、总结

1、按照JS的数据类型来说,基本数据类型(即值类型,包括:undefined、null、number、string、boolean、symbol)存在栈中,引用类型(即:object array function)存在堆中。

2、基本数据类型有固定的大小和值,存放在栈中,而引用类型不确定大小,但是其引用地址是固定的,因此,它的地址存在栈中,指向存储在堆中的对象。

3、基本数据类型,在当前环境执行结束时销毁,而引用类型只有在引用的它的变量不在时,会被垃圾回收机制回收。

4、复制方式不一样,值类型的是深复制(深拷贝),引用类型的是浅复制(浅拷贝),变量的复制其实是引用的传递。

5、值类型不可添加属性和方法,而引用类型可以添加属性和方法。

6、值类型比较相等,就可以用 == 或者 ===来比较,但是对于引用类型,即使let s = {};let s1 = {};但因为他们的内存地址不一样,比较结果依然不相等。
 

五、堆和栈的溢出

(1)如果想要堆溢出,比较简单,可以循环创建对象或大的对象;
(2)如果想要栈溢出,可以递归调用方法,这样随着栈深度的增加,JVM (虚拟机)维持着一条长长的方法调用轨迹,直到内存不够分配,产生栈溢出。

 

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JavaScript中,是用来存储变量和数据的两种不同的内存区域。 是一种后进先出(LIFO)的数据结构,用于存储基本类型的变量和引用类型的指针。当我们声明一个变量时,它的值会被直接存储在内存中。基本类型的值(如数字、布尔值、字符串等)被直接存储在中,而引用类型的变量则存储了指向内存中实际数据的指针。 是一种动态分配的内存区域,用于存储引用类型的数据。当我们创建一个引用类型的变量时,它的值实际上是一个指向内存中对象的引用。对象本身的数据存储在内存中,而中的变量只是存储了指向内存中对象的引用。 深拷贝是指创建一个新的对象,将原始对象的所有属性和嵌套对象的属性都复制到新对象中。这样,新对象和原始对象是完全独立的,对新对象的修改不会影响原始对象。在JavaScript中,可以使用不同的方法实现深拷贝,如使用JSON.parse(JSON.stringify(obj))或自定义递归函数来复制对象的属性和嵌套对象。 浅拷贝是指创建一个新的对象,将原始对象的属性复制到新对象中,但嵌套对象的引用仍然指向原始对象中的相同嵌套对象。这意味着对新对象的修改可能会影响原始对象。在JavaScript中,可以使用Object.assign()或展开运算符(...)来实现浅拷贝。 总结来说,用于存储基本类型的变量和引用类型的指针,而用于存储引用类型的数据。深拷贝是创建一个新对象并复制所有属性和嵌套对象的值,而浅拷贝只复制属性,嵌套对象的引用仍然指向原始对象。 #### 引用[.reference_title] - *1* *3* [JavaScript区别](https://blog.csdn.net/qq_29850249/article/details/110500006)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [JavaScript中栈内存与内存分别是什么?](https://blog.csdn.net/qq_43807473/article/details/123816682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕穗子博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值