JavaScript中对栈和堆的理解

堆和栈的理解

是堆内存的简称。
是栈内存的简称。

各种语言在处理堆栈的原理上都大同小异。堆是动态分配内存,内存大小不一,也不会自动释放。栈是自动分配相对固定大小的内存空间,并由系统自动释放。

堆和栈都是运行时内存中分配的一个数据区,因此也被称为堆区和栈区,但二者存储的数据类型和处理速度不同。

  • 堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象(引用类型的值通常大小不固定,所以被存储在堆内存中);它是运行时动态分配内存的,因此存取速度较慢。
  • 栈(stack)中主要存放一些基本类型(Undefined、Null、Boolean、Number 和 String)的变量和对象的引用(基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中),其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

1.栈的使用规则
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。例如下面的代码定义两个变量,变量的值都是数字类型。

var a=3;
var b=3;

JavaScript解析器先处理 var a=3;,首先会在栈中创建一个变量为a引用,然后查找栈中是否有3这个值,如果没有找到,就将3存放进来,然后将a指向3。接着处理 var b=3;,在创建为b的引用变量后,查找栈中是否有3这个值,因为此时栈中已经存在了3,便将b直接指向3。这样,就出现了a与b同时指向3的情况。此时,如果再令a=4,那么JavaScript解释引擎会重新搜查栈中是否有4这个值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
2.堆的使用规则
下面通过Array来看一下堆的行为,例如存在下面的代码:

var name="jack";
var age=18;
var gender="男";
var arr=[name,age,gender];
var newArr=arr;

当创建数组时,就会在堆内存创建一个数组对象,并且在栈内存中创建一个对数组的引用(即引用类型在栈内存中存放的只是该对象的访问地址,而在堆内存中为这个值分配空间存储)。变量nameagegender为基本数据类型,它们的值直接存放在栈中;newArrarr为复合数据类型(引用类型),他们的引用变量存放在栈中,指向于存放在堆中的实际对象。
注意,newArr的值等于变量引用arr,所以它也是复合数据类型(引用类型)。此时,如果更改变量nameagegender的值,那么其实是更改栈中的值;如果更改newArrarr的值,那么其实是更该堆中的实际对象,因此,对两个变量引用都会发生作用(因为从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象)。例如,首先更改newArr的值,然后看arr的值,代码如下:

console.log(arr[1]);// 返回 18
newArr[1]=22;
console.log(arr[1]);// 返回 22

同样,首现更改arr的值,然后看newArr的值,代码如下:

console.log(newArr[0]);// 返回 "jack"
arr[0]='rose';
console.log(newArr[0]);// 返回 "rose"

JavaScript堆不需要程序代码来显示地释放,因为堆是由自动的垃圾回收来负责的,每种浏览器中的JavaScript解释引擎有不同的自动回收方式,但一个最基本的原则是:如果栈中不存在对堆中某个对象的引用,那么就认为该对象已经不再需要,在垃圾回收时就会清除该对象占用的内存空间。因此,在不需要时应该将对对象的引用释放掉(解除引用),以利于垃圾回收,这样就可以提高程序的性能。释放对对象的引用最常用的方法就是为其赋值为null,这种做法适用于大多数全局变量和全局对象的属性。局部变量会在他们离开执行环境时自动被解除引用,例如下面代码将newArray赋值为null:

newArray=null

注意:解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值