闭包中的变量存储在哪里 - 堆栈或堆?

Posted

技术标签:

【中文标题】闭包中的变量存储在哪里 - 堆栈或堆?【英文标题】:Where are variables in a closure stored - stack or heap? 【发布时间】:2015-05-27 08:42:41 【问题描述】:

如下代码:

var foo = function() 
    var a = 1; // closure var
    return function()  // closure fun
        console.log(a);
    
;
var bar = foo();

当 foo 退出(或者说,返回)时,我们知道变量 a 不会被销毁并保留在内存中(这就是闭包起作用的原因)。所以我的问题是存储、堆栈或堆的变量在哪里?

【问题讨论】:

【参考方案1】:

闭包只是堆栈概念的演变。

堆栈用于在调用函数时分离/隔离作用域。当函数返回堆栈帧(激活记录)时,堆栈帧(激活记录)会从调用堆栈中弹出,从而释放已使用的内存,允许下一个函数调用将该 RAM 重用于其堆栈帧。

闭包的作用是,如果该堆栈帧中有任何对象/变量被其他任何东西引用,那么它会保留该堆栈帧以供将来使用,而不是实际释放该堆栈帧。

大多数语言通过将堆栈实现为链表或哈希表而不是平面数组来实现这一点。这样,堆栈可以在运行时重新排序,并且不受物理内存布局的限制。

所以。考虑到这一点,答案是闭包中的变量存储在堆栈和堆中。取决于你的观点。

从语言的角度来看,它肯定是堆栈。因为这就是理论上的闭包 - 修改后的堆栈。

从机器语言或底层 C/汇编代码的角度来看,链表堆栈的想法是无稽之谈。因此高级语言必须使用堆来实现它的“栈”。

因此变量在堆栈中,但该堆栈可能位于堆中。

这当然取决于您的编程语言的实现。但是上面的描述对大多数 javascript 解释器都有效(当然是我见过的所有解释器)。

【讨论】:

关于闭包机制如何在内存级别工作的描述请参见:***.com/questions/26061856/… 所以闭包是基于环境模型的,它是对底层堆栈/堆模型的另一层抽象?谢谢!

以上是关于闭包中的变量存储在哪里 - 堆栈或堆?的主要内容,如果未能解决你的问题,请参考以下文章

彻底搞懂JavaScript中的作用域和闭包

js 闭包 具体作用?

前端知识体系:JavaScript基础-作用域和闭包-闭包的实现原理和作用以及堆栈溢出和内存泄漏原理和相应解决办法

闭包是用来做啥的(js)?

C++ 对象存储在堆栈或堆中

JS闭包