首页 > 解决方案 > Javascript调用堆栈是否存在于堆中?

问题描述

一切都是javascript中的对象。这是否意味着调用堆栈与内存的堆栈部分无关,而函数调用只是堆叠在堆部分中?

标签: javascriptstackheap-memory

解决方案


javascript中的一切都是对象

这不是真的。基元是基元,除非您将它们用作对象。JavaScript 引擎可以将数字存储为例如 32 位整数或 64 位浮点数。

在调用堆栈的上下文中更重要的是变量可以保存不同类型的值,因此变量可能保存不同大小的不同值。因此,一个非常幼稚的实现可以将指针分配到堆栈上,然后这些指针将指向不同大小的对象(或包装在某个容器中的原语)。

现在的引擎通常并不幼稚,他们可以很容易地假设某些变量在某个时间持有某些变量类型,然后他们可以直接将固定大小的数据结构分配到堆栈上。

函数调用只是堆叠在堆部分?

函数变量在内存中表示为堆栈的原因是函数可能会递归调用自身,因此对于一个函数可以存在多个值。堆栈是一个不错的选择,因为变量的地址可以很容易地从堆栈指针中计算出来(一个加法):

 function fn() {
   var a = 1, b = 2;
   fn();
 }

// how the stack of might look like (very simplified)
//                           v stackpointer
adress | 0 | 1 | 2 | 3 | 4 | 5
value  | 1 | 2 | 1 | 2 | 1 | 2

// some pseudo Cish code
void* stackpointer = 5;
int currentB = (stackpointer)*
int currentA = (stackpointer - 1)*

然而,如果变量的大小是已知的,这只是那么容易。堆栈在内存中的分配位置并不重要,只是所有值都是固定大小的。

也没有“堆栈”,如果您调用异步函数,它们的执行可能会暂停,并且对于每个暂停的函数,某种形式的调用堆栈必须保留在内存中。所以总是有一个堆栈当前正在执行,最终有多个堆栈被暂停。有人可能会说当前正在执行的堆栈是“堆栈”,而其他堆栈是“在堆中”,尽管这种区别不是很有用,尤其是因为可能还存在多个堆(例如,用于字符串的堆、堆对于对象,...)。


推荐阅读