微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Javascript 在哪里为函数调用的结果分配内存?堆栈还是堆?

如何解决Javascript 在哪里为函数调用的结果分配内存?堆栈还是堆?

我查遍了整个互联网,似乎找不到这个问题的答案。

  • 我读到堆栈用于存储基元,而堆用于存储对象。

  • 我也知道原语是不可变的,所以如果我们尝试重新分配一个变量,它不会更改其内存地址处的值,而是会在内存中分配新空间,存储新值并分配其地址到变量。

如果以上是正确的,那么当我这样做时会发生什么?

let string = "Hello World"; // Memory allocated for "Hello World"
string = string.toupperCase(); // New memory allocated for "HELLO WORLD"

HELLO WORLD 的新内存在哪里分配?它在堆栈中是因为它是一个原始类型吗?还是因为JS在运行代码之前不知道它的值在堆中?

如果它在堆栈中,那么旧的“Hello World”会发生什么?既然只有堆被垃圾回收,这是否意味着旧的、未使用的字符串会一直留在那里直到程序完成运行?

如果我这样做了会怎样

string = string.repeat(10000000000)

如果堆栈不能增长,是否意味着在某个时候我会因为变量太大而导致堆栈溢出?

谢谢。

解决方法

答案可能因引擎而异,这与您的代码无关。如果/当您用完堆栈时,请担心堆栈用完。 JavaScript 的规范不要求实现做一件事或另一件事。它描述的是行为,而不是该行为的实现。

但实际上:JavaScript 引擎似乎不太可能尝试将大量字符串放入堆栈中。更有可能的是,它会将它放入堆中。这并不意味着它不能将 other 字符串放入堆栈中。也许它根据大小决定。也许它根据生命周期来决定——也许它会将一个仅在函数本地使用的小字符串放在堆栈上,但将一个大字符串或全局保留的字符串放在堆上。

重点是:现代 JavaScript 引擎复杂且高度优化。他们不太可能采取“原语放在堆栈上,对象放在堆上”这样简单的观点。

我读到堆栈用于存储原语,而堆用于存储对象。

不一定。对象也可以在堆栈上分配,并且至少在历史上的不同时间点被一些 JavaScript 引擎使用。如果一个对象在函数调用结束后无法生存,并且不是很大,那么将它放在堆栈中可以在函数返回时轻松回收它。

我也知道原语是不可变的,所以如果我们尝试重新分配一个变量,它不会改变其内存地址处的值,而是会在内存中分配新空间,存储新值并将其地址分配给变量.

在没有深入理论的情况下,这很可能是特定于实现的。考虑a = 1。我们无法判断是将值 1 放入与 a 关联的内存中,还是将一个对表示 1 的不可变单例的引用放入 a。前者似乎比后者更有可能很多(对于数字;字符串是另一回事),但我们不知道也不能知道(在一般情况下;我们可以针对特定的特定引擎的版本),因为它对我们的代码没有影响,并且规范不需要一种行为或另一种行为。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。