JavaScript有内存堆吗?

23

换句话说,我在JavaScript中有哪些选项可以分配内存?

我知道你可以在全局范围或函数作用域内分配内存。我能动态地分配内存吗? new操作符到底是什么意思?

编辑:这里有一个具体的例子。您如何实现从用户读取整数值 - n,然后读取n个整数到数组中?


针对“具体示例”,只需使用.push()将值推入数组中。然后使用const n = read()const arr = []; for (let i = 0; i < n; i += 1) { arr.push(read()) }。在JS中,“数组”在内存意识语言中被称为“向量”。 - Félix Saparelli
对于后来查看此问题的人:在像JS这样的语言中,堆和栈并不是固有的,而且可能会相当依赖于实现。V8具有堆和栈的分离,以及nullundefinedtruefalse,虽然是原始类型,但实际上是在堆上分配的。这个答案https://dev59.com/P2w15IYBdhLWcg3wcrdC#6604390有更多细节。对于普通的JS程序员来说,这更像是实现细节。 - xji
7个回答

24

你不能分配内存。你可以创建对象。这就是new的作用。

现在,JavaScript是一个奇怪的生物:在JavaScript中,函数也是对象。这意味着你可以使用new实例化几乎所有东西。

因此,new操作符表示正在创建一个新对象。

Javascript也会像Java一样垃圾回收这些变量,如果你了解Java,那么很容易就能看到它们之间的相似之处。

祝好!

jrh

PS:当你分配对象时,你确实在分配内存。只是你没有显式地做这件事。你可以分配一个数组,并使它像一个内存缓冲区,但这将严重降低JavaScript的性能:JavaScript数组不是内存缓冲区,它们也是对象(像其他所有东西一样)。


7

JavaScript有垃圾回收机制,会自动处理这个问题。

然而,在适当的情况下,您可以使用delete运算符来帮助它。

来自Apple JavaScript编码指南

就像您使用new运算符创建对象一样,当您完成对它们的使用时,应该删除对象,如下所示:

delete myObjectVariable;

JavaScript运行时在将对象的值设置为null时自动进行垃圾回收。但是,将对象设置为null并不会从内存中删除引用对象的变量。使用delete可以确保回收除对象本身使用的内存之外的此内存。(如果您显式调用delete,还可以更轻松地看到分配和释放不平衡的位置。)

史蒂夫


1
我刚读了一篇文章,说这是个坏主意:“在许多关于在JavaScript中回收内存的在线讨论中,delete关键字被提出来,因为尽管它原本只用于从映射中删除键,但一些开发人员认为可以使用它来强制取消引用。如果可以的话,请避免使用delete。”有关更多详细信息,请访问http://goo.gl/2Abpe9的“取消引用误解”部分。 - gtournie

5

听起来你是从注重内存的编程语言转换到JS,试图将那种逻辑强行套入JS中。是的,JS也会使用内存(当然),但我们有垃圾回收机制来处理清理所有内容。

如果您想了解有关内存分配细节的具体信息,则必须搜索相关内容。但通常情况下,当您使用var、new或声明新函数(或闭包)时,都会占用内存。您可以将变量设置为null以标记它们进行垃圾回收,也可以使用delete关键字,尽管很少有人这样做,除非他们在服务器端工作(如我使用ASP JScript),这是非常重要的。


4

Javascript真的非常友好 - 实际上过于友好了!

如果您有一个包含3个元素的数组,并且想要添加第四个元素,您可以像该数组位置已经存在一样进行操作:

    var arr = ['zero', 'one', 'two'];
    // Now you have arr[0], arr[1] and arr[2].
    // arr.length is equal to 3.
.
    // to add arr[8]:
    arr[8] = 'eight';
    // Now you have arr[0] through arr[8]. arr.length is equal to 9.
    // and arr[3] through arr[7] exist, and 
    // are initialized to undefined. (If I remember right.)

因此,在添加元素时,非常具体的内存分配是不必要的。

3

不需要也无法分配内存。JavaScript解释器会自动完成这个过程。


我不能同意那个说法。对我来说,var i = 0 是内存分配。如果我不分配内存,我就不算在编程了。 - Yuval Adam
1
所以您更想知道 var 用于什么以及为什么应该使用它? - Gumbo
1
“内存分配”的含义是指定您想要的字节数,分配它们(接收到引用已分配的内存的方式),然后将东西存储在那里。由于JScript为您处理所有这些,因此术语“内存分配”不是发生的好名称选择。 - Brian Wren

2
回答这个问题的标题,如果您相信MDN,大多数JavaScript实现都有一个堆:

对象分配在堆中,这只是一个名称,表示一个大多数未结构化的内存区域。
多个运行时通信
Web Worker或跨源iframe具有自己的堆栈、堆和消息队列。两个不同的运行时只能通过发送消息通过postMessage方法进行通信。如果后者监听消息事件,则此方法将向其他运行时添加消息。
对于更深入的内存管理,还有一篇文章here,尽管其中许多内容是特定于实现的。

0

在Javascript中,您不需要手动管理内存。堆和栈都在底层用于管理内存,这取决于实现方式。通常,局部变量在栈上,对象在堆上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接