Javascript数组到链表,并了解内存

Javascript数组到链表,并了解内存,javascript,memory,linked-list,Javascript,Memory,Linked List,我使用以下代码将数组转换为链表: function arrayToList(array) { var list = null; for (var i = array.length - 1; i >= 0; i--) list = {value: array[i], rest: list}; return list; } 这个代码是给我的,所以我试着去理解它。我得到了它的基本直觉/要点(我使用过链表,已经用Java学习过数据结构类,了解C语言中指针的基本知识),等等 但

我使用以下代码将数组转换为链表:

function arrayToList(array) {
  var list = null;
  for (var i = array.length - 1; i >= 0; i--)
    list = {value: array[i], rest: list};
  return list;
}
这个代码是给我的,所以我试着去理解它。我得到了它的基本直觉/要点(我使用过链表,已经用Java学习过数据结构类,了解C语言中指针的基本知识),等等

但是,有些东西没有点击,我想确保我能看到发生了什么。因此,让我们考虑创建一个变量,<强>列表< /St>,引用其值被声明为NULL的内存空间。假设这个的“内存地址”是0001:

0001:[null]列表

那么在循环的第一次迭代之后会发生什么呢?这是我的解释列表现在指的是一块新的空间。也就是说,通过在行中重新定义列表

list = {value: array[i], rest: list};
我们创建了一个占据新空间的“新”对象。所以现在我们可能有:

0001:[null]
0002:[数组[i]]列表。值
0003:[null]列表。rest

(假设0002,我不太确定list现在“指向”的确切位置,尽管从概念上来说,我想这在Javascript中是没有意义的)

这种理解正确吗?我习惯于将数据结构视为la Java,其中像list这样的对象已经在每次创建实例时定义了空间块。我使用过Python,但以前没有用它构建过链表。由此,我假设像Javascript这样的语言是流动的,您可以让一个变量为null,然后让它引用一个散列,然后当您将它设置为另一个散列时,它会创建一个“新”散列,等等


谢谢

首先,JavaScript中没有本机数据结构,它是一个链表,我们有对象和数组(它们是对象的特例)

您在这里向我们展示的代码通过使用对象文本生成对象


这似乎更像是在
=

=
的右侧上的变量将指向在左侧上更改之前的对象

相当于

var foo = {};

var t = foo;
foo = {"fizz": t}; // `foo` becomes a new object in a different memory location
// that points to `t`s target, meaning that `t` is referencable through `foo` and so
// won't be GC'd if the identifier `t` is cleaned up from namespace
根据通常的从左到右的执行顺序,您可能会发现这是违反直觉的,但如果您仔细考虑,在知道要设置什么之前,您无法“设置”,因此在RHS完成之前,您无法从LHS更新标识符


所以如果你循环这个,你可能会得到这样的结构

foo;           // Object @ e.g. 0x30
foo.fizz;      // Object @ e.g. 0x20
foo.fizz.fizz; // Object @ e.g. 0x10
foo.fizz.fizz.fizz; // undefined

其中每个对象都有自己的哈希映射,该映射指向上一个对象(在查找fizz时),直到对象用完为止,并且没有任何内存获得GCd,因为每个对象仍然可以访问。规范中没有规定环境如何实际实现这一点,因此对象的内存位置永远不会移动并不是一项要求,但它在内存中的位置不是您能够看到或与之交互的(都是在幕后完成的)。因此,出于所有环境目的,您可以将内存位置视为静态的。

我认为OP讨论的是如何在JavaScript内存中存储链表,而不是如何在这个抽象层中设置对象。您是说OP的代码实际上生成了一个
链表
foo;           // Object @ e.g. 0x30
foo.fizz;      // Object @ e.g. 0x20
foo.fizz.fizz; // Object @ e.g. 0x10
foo.fizz.fizz.fizz; // undefined