我有以下代码将数组转换为链表:
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中指针的基础知识)等。
然而,有些事情没有点击,我想确保我能看到发生了什么。因此,我们考虑创建一个变量 list ,引用其值被声明为 null 的内存空间。让我们说这个"内存地址"这是 0001 :
0001 :[ null ] 列表
那么在循环的第一次迭代之后会发生什么?这是我的解释。 list 现在指的是一大块空间。也就是说,通过在行中重新定义列表:
list = {value: array[i], rest: list};
我们创建了一个新的"占据新空间的物体。所以现在我们可能有:
0001 :[ null ]
0002 :[ array [i] ] list.value
0003 :[ null ] list.rest
(我不太确定列表在哪里"指向"到现在为止,假设 0002 ,虽然从概念上我猜这&# 39; Javascript中的那种模式)
这种理解是否正确?我过去常常把数据结构想象成Java,其中像 list 这样的对象在每次创建实例时都已经定义了空间块。我曾经使用过Python,但之前没有使用它构建链表。从这里我假设像Javascript这样的语言是流动的,你可以只有一个变量为null,然后让它引用一个哈希,然后当你将它设置为另一个哈希时,它会创建一个" new"哈希等。
谢谢!
答案 0 :(得分:1)
首先, JavaScript 中没有本地数据结构,这是链接列表,我们有对象,我们有数组(令人困惑的是 Objects 的特殊情况)。
您在此处向我们展示的代码通过使用对象文字来生成对象。
这似乎是关于在=
=
的 RHS 上的变量将指向 LHS
// say we have
var foo = {};
// Then
foo = {"fizz": foo};
等同于
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
每个 Object 都有自己的哈希映射,指向前一个(查找 fizz 时),直到用完 Objects ,并且没有内存获得GCd,因为每个内存仍然可以访问。规范中没有指定环境如何实际实现这一点,因此不需要 Object 的内存位置,但它在内存中的位置不是你能看到或与之互动的东西(它都是在幕后完成的)。因此,对于所有环境内目的,您可以将内存位置视为静态。