Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 与此代码的使用方式混淆';s变量被放入JS中的堆栈和堆中_Javascript - Fatal编程技术网

Javascript 与此代码的使用方式混淆';s变量被放入JS中的堆栈和堆中

Javascript 与此代码的使用方式混淆';s变量被放入JS中的堆栈和堆中,javascript,Javascript,我是JS新手,对变量如何放入堆栈和堆感到困惑。比如说, 设num=5; 设obj={}; 函数showNum(){ 设num2=8; 设obj2={} 控制台日志(num2); } showNum()全局 在概念上(例如,根据规范),全局变量作为绑定保存在。绑定是名称、当前值和与绑定相关的两个标志(是否可变以及是否初始化)的组合 当然,实际上,JavaScript引擎可以用它喜欢的任何方式存储它们,只要它的行为符合规范的语义 细节将取决于JavaScript引擎的具体情况,但似乎全局绑定将保存

我是JS新手,对变量如何放入堆栈和堆感到困惑。比如说,

设num=5;
设obj={};
函数showNum(){
设num2=8;
设obj2={}
控制台日志(num2);
}
showNum()全局
在概念上(例如,根据规范),全局变量作为绑定保存在。绑定是名称、当前值和与绑定相关的两个标志(是否可变以及是否初始化)的组合

当然,实际上,JavaScript引擎可以用它喜欢的任何方式存储它们,只要它的行为符合规范的语义

细节将取决于JavaScript引擎的具体情况,但似乎全局绑定将保存在堆中

当地人 从概念上讲,局部变量也保存在环境记录中,环境记录是为与局部变量相关的函数调用创建的,在函数调用终止时可以回收,也可以不回收。我将在中对此进行详细介绍,但简单地说,如果在被调用的函数中创建的任何函数在函数返回后仍然存在,则从概念上讲,它引用了环境记录(更准确地说,引用了与该记录相关的环境记录),这就是为什么关闭局部变量的函数可以在包含它们的函数返回后继续访问这些局部变量

实际上,JavaScript引擎可以以任何方式执行此操作,只要它符合规范中的语义,并且现代引擎经过高度优化。如果可能的话,他们会在堆栈上放置局部变量(包括对象)。如果局部变量被函数调用期间创建的闭包引用,而闭包在函数终止后仍然存在,引擎将首先将它们放在某种环境记录对象中,或者将它们从堆栈中移到那里


你的具体问题:

全局变量是否附加到全局执行上下文的堆栈(num)和堆(obj),因为它们不是局部变量

它们是全局执行上下文的词法环境的环境记录中的绑定。这与堆栈和堆的关系是一个实现细节

当函数被执行并推入调用堆栈时,
num2
obj2
(我的意思是
obj2
的引用被放入调用堆栈)变量也会被放入调用堆栈吗?因为我认为stack=callstack

同样,这是上面讨论的实现细节。请注意,本地地址和返回地址(以及其他调用元数据)都使用同一堆栈是很常见的,但情况并非如此。这取决于实施

最后,在调用堆栈中弹出showNum()之后,
num2
变量也会从堆栈中删除,除了垃圾收集器删除的
obj2

概念上:由于
showNum
在返回时不创建任何继续存在的函数,因此它的词法环境和关联的环境记录在返回时都被释放


实际上,这又一次取决于实施。在优化引擎中,
num2
obj2
(包含对对象的引用)和对象可能都存储在堆栈上(毕竟对象非常小),因此弹出堆栈会立即回收所有内存。或者可能是
num2
obj2
在堆栈上,但是
obj2
引用的对象在堆中,因此弹出堆栈只会删除
num2
obj2
,使对象没有未完成的引用,这意味着它符合垃圾收集的条件。它是特定于实现的。

堆栈可能重复!=调用堆栈。堆栈是执行方法时存储本地值的内存区域。callstack是一组相互调用的方法的返回地址。@WiktorZychla-True,尽管通常一个堆栈用于两个目的,局部变量和返回地址(以及调用所需的其他元数据)。@T.J.Crowder,嘿,Crowder先生,很高兴你注意到我的问题:)。Crowder先生,根据你上面的评论,我可以肯定地认为Stasts是“调用堆栈”,意思是堆栈=调用堆栈右?“狄更斯,我不知道你为什么在乎。”您无法判断一个实现是对局部变量和调用信息使用单个堆栈,还是对它们使用单独的堆栈。它不会以任何方式影响您的代码,除了通过检查特定实现的源代码和/或使用它提供的开发人员工具(希望这些工具能够向您展示)深入了解特定实现的细节之外,您没有其他方法可以告诉您。