首页 > javascript 引用类型 基本类型的数据 堆内存 栈内存

javascript 引用类型 基本类型的数据 堆内存 栈内存

javascript 引用类型的数据存放在堆内存,基本类型的数据存放在栈内存。
我的疑问是,引用类型的数据最终也是由基本类型的数据组成的,那组成应用类型的这些基本类型的数据存放在堆内存还是栈内存?


写了一大堆,我再补充一下吧:
问题中的堆和栈到底指的是什么?有这么几种可能:

  1. JS语言本身意义上的堆和栈。但是实际上JS语言本身并没有堆和栈。

  2. JS某个具体的解释器(虚拟机)使用的语言中的堆和栈。比如你用Java写了一个JS的运行环境,你把JS中的函数映射成Java中的一个方法,函数局部变量映射成了Java中方法的局部变量,这样一来基本类型的数据确实存到JVM的栈上了。

  3. 最终的机器码执行时,对应的操作系统的堆和栈。

所以如果不说清楚堆和栈是哪里的堆和栈,那么题主在问题里提到的:

javascript引用类型的数据存放在堆内存,基本类型的数据存放在栈内存。

是不准确的。

原答案:

这个问题实际上没那么简单。

建议先看一下这个问题:https://.com/q/1010000002579830

说一下我的看法:

首先,当我们谈到某种语言的数据怎么存储时,实际上需要考虑到这种语言的编译器或解释器(或虚拟机)的实现。

比如C语言要编译成二进制代码,二进制代码是由操作系统在真实的CPU上直接运行。操作系统的内存管理机制会把内存分成堆、栈等区域。C语言中

int a = 1;
int *b = (int*)malloc(..);

a和b(指向的那个数)分别被分配在栈和堆上。

又如Java要被编译成字节码,字节码要在JVM这个虚拟的计算机上运行。JVM也提供了栈区和堆区。Java中

int a = 1;
Person p = new Person();

a和p(指向的那个对象)分别被分配在JVM的栈和堆上。

看到这里就明白了,JavaScript中的数据存在哪里,是跟JS语言的具体实现有关的。JS引擎那么多,都有自己的实现方式。ECMAScript规范本身并没有规定数据怎么存、存在哪里,也没有规定堆和栈的概念。JS也没有一个像Java那样的官方的《JVM虚拟机规范》。所以可以说这个问题实际上根本没法讨论。

如果仅从ES(5)规范的角度看:实际上JS引擎(JS虚拟机)实现时,压根不需要栈的概念。我们知道,栈通常是指函数执行时用的栈。在JS中对应于执行上下文(EC)栈,但是这个栈仅仅是一个逻辑上的概念。在实现时,假设用Java来实现一个JS的虚拟机,我们完全可以把执行上下文实现成一个Java对象,词法环境也实现成一个对象。变量的名字都是挂在词法环境上的,可以实现为Java对象的字段。的这样一来不管原始类型还是引用类型,实际上都是存在JVM的堆里的。

所以,这个问题实际没有意义,也没有结论。根本在于没有一个标准或规范定义JS的实现者应该如何分配内存,甚至连堆和栈的概念都不一定需要。

当然你可以具体到某个具体的实现比如v8,不过我不了解它的实现细节,就不敢多说了。


你这么理解是有误区的,你把两个概念揉在一起了。简单的说并不是引用类型就存在堆内存,基础类型就存在栈内存。这两个概念不能一概而论。

对于你所描述的,复合数据类型也是由基础类型组成的,那他们存在哪?这里并不是看他们是什么类型来决定他们存在哪,而是要看他们的声明方式来决定他们存在哪。

存储在栈内存中的,主要是根据程序逻辑明确需要申请的内存,也就是在编译或者解析代码时就能知道这块内存是必须申请的。
而存储在堆内存中的,大多是动态申请的内存,也就是程序执行后才能知道这块内存是否需要申请的。

在Javascript中,复合数据类型都以对象的形式存在,而对象基本都是以new的方式申请内存的,所以基本上所有的复合数据都存储在堆内存中。注意,这里是指对象内的数据,而大部分的对象指针,也就是对象的引用,都是以栈内存的形式申请的。

【热门文章】
【热门文章】