简述数据结构:栈内存与堆内存的存储方式 js中的原始值

在讨论堆栈前,先要明确什么是原始值、引用值。
1.变量可以存放两种类型的值: 原始值 和 引用值
2.原始值代表原始数据类型的值,也叫基本数据类型,包括 Number、Stirng、Boolean、Null、Underfined。
3.引用值指的是复合数据类型的值,包括 Object、Function、Array、Date、RegExp。

原始值

存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。

引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
根据数据类型的的不同,有的变量存储在栈中,有的存储在堆中。

对于栈内存栈内存之间的值是拷贝关系,当改变一个栈的内容,不会影响其它栈的内容,栈与栈是互相不影响的。其取值规则是,先进后出。

所以在栈内存中,原始值直接拷贝的是原始值的值。

p.s 栈内存中的原始值一旦给定,就不可修改,像a=20,这种操作,系统内部会新开一个栈内存,其值为20,内存名从1011移到1010。

var a = 10;        
var b = a;
a=20;
//这时候改变

在上面程序中,a变量先取出10,拷贝一份放到b里面去,此时b的值为10,它是a的副本,这个时候无论是更改a或b,对另一个值无影响。
在这里插入图片描述

反过来,堆内存和栈内存是不一样的,栈内存就好比是储物格子,怎么放的就怎么拿,没有栈的那种存放顺序。

引用值是将其地址存放在栈中,将值存放在对内存中,所以在引用值拷贝引用值的时候,得到的是地址。所以当两个栈内存中的地址同时指向堆时,此时改变堆的值,将会影响栈内存中两个变量的值。

var arr = [1,2];        
var arr1 = arr;        
document.write(arr+"<br>");       
document.write(arr.push("3") + "<br />")

在上面程序中arr与arr1的值都被改变了,都为[1,2,3]。这也说明push方法,是直接将收到的参数,按顺序插入到arrayObject的尾部,它是直接修改arrayObject,而不是创建一个新的数组。

如果此时再给arr赋一个新的值,arr1的值是不会变的,相当于开了一个新的内存。

在这里插入图片描述

总结:

  • 原始变量类型及他们的值存储在栈中,当吧一个原始变量传递给另一个原始变量时,是把一个一段栈空间的内容复制到另一段栈空间,这两个原始值互相不影响。

  • 引用值是把引用变量的名称存储在栈中,但是把其实际对象存在堆中,且存在一个指针有变量名指向存储在堆中的实际对象,当吧引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不通过方法,而是通过重新赋值,此时相当于重新开了一段内存,该值的原指针改变 ,则另外一个值不会随他的改变而改变。

  • Number、Stirng、Boolean、Null、Underfined这些基本数据类型,他们的值直接保存在栈中;

  • Object、Function、Array、Date、RegExp这些引用类型,他们的引用变量储存在栈中,通过指针指向储存在堆中的实际对象

猜你喜欢

转载自blog.csdn.net/qq_28766729/article/details/83213906
今日推荐