简体   繁体   English

在 JavaScript 中,分配给变量的对象如何跟踪未来的变化?

[英]In JavaScript, how does an object assigned to a variable keeps track of future mutations?

I have been practicing data structures with JavaScript recently and I found a snippet of code that I can't wrap my head around.我最近一直在用 JavaScript 练习数据结构,我发现了一段我无法理解的代码片段。 I understand that when you assign an object to a variable, and then mutate the object, the original variable can "see" those mutations because when you assign the object to the variable you are not cloning the object, you are just passing a reference to it.我知道当你将一个对象分配给一个变量,然后改变该对象时,原始变量可以“看到”这些变化,因为当你将对象分配给变量时,你不是在克隆对象,你只是将引用传递给它。 However, the following code baffles my mind:但是,以下代码让我感到困惑:

function ListNode(val, next) {
  this.val = (val === undefined ? 0 : val)
  this.next = (next === undefined ? null : next)
}

let tempList = [1, 1, 2, 4, 4, 100];

let point = new ListNode(tempList[0]);
let head = point;

for (let i = 1; i < tempList.length; i++) {
  point.next = new ListNode(tempList[i])
  point = point.next;
}

console.log(head); // Outputs the Linked List 1 -> 1 -> 2 -> 4 -> 4 -> 100

So when I try to follow the logic in my head, I picture it as follows:因此,当我尝试遵循头脑中的逻辑时,我将其描绘如下:

In the first iteration, head and point hold the following information:在第一次迭代中, headpoint持有以下信息:

{
  val: 1,
  next: null
}

In the second iteration, point first holds this information:在第二次迭代中, point first 保存了以下信息:

{
  val: 1,
  next: {
    val: 1,
    next: null
  }
}

and so does head , but then the next step is what is confusing me. head也是如此,但下一步是什么让我感到困惑。 In my head, I'm overriding the current value of point with the newly created Node in the step before, so the variable should look like this:在我的脑海中,我在之前的步骤中使用新创建的 Node 覆盖了point的当前值,因此变量应如下所示:

{
  val: 1,
  next: null
}

and head since it's just holding a reference from point should look like that as well.head因为它只是从point持有一个参考也应该看起来像那样。 HOWEVER, head looks as follows:但是, head看起来如下:

{
  val: 1,
  next: {
    val: 1,
    next: null
  }
}

and as the iterations keep going, obviously, head keeps track of all the linked nodes.并且随着迭代的继续进行,显然head会跟踪所有链接的节点。 That's the desired behavior, but I do not fully comprehend HOW that happens.这是所需的行为,但我不完全理解这是如何发生的。 Can somebody explain me why this is the case?有人可以解释我为什么会这样吗?

When you reassign point it doesn't affect the reference in head .当您重新分配point它不会影响head的引用。 It still refers to the first ListNode that was created.它仍然指的是创建的第一个ListNode

It's no different from doing something like this:这与做这样的事情没有什么不同:

let point = 1;
let head = point;
point = point + 1;

Reassigning point doesn't change the value of head , even though they were equivalent at first.重新分配point不会改变head的值,即使它们一开始是等价的。

If you're familiar with languages like C or C++, you can think of the reference as being like a pointer.如果您熟悉 C 或 C++ 等语言,您可以将引用视为指针。 You start with two pointers to the same address, then reassign one of them;您从指向同一地址的两个指针开始,然后重新分配其中一个; that won't change the other pointer.这不会改变另一个指针。

In JavaScript variables don't bind to other variables.在 JavaScript 中,变量不绑定到其他变量。 They bind to the value of the variable at the time, which in your case is the initial point object.它们绑定到当时变量的,在您的情况下是初始point对象。

It sounds like your mental model is telling you head -> point -> {} when in reality both point to the same object , therefore binding point to a new object does not affect head .听起来你的心智模型告诉你head -> point -> {} 实际上两者都指向同一个对象,因此绑定到新对象的point不会影响head

head is not in the loop, therefore you're never actually updating the value of head once you've bound it to the first object point is bound to. head不在循环中,因此一旦将head绑定到第一个对象point绑定到的第一个对象,您就不会实际更新head的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM