[英]Why does my JS object incorrectly change when not assigning the object to a variable?
Please explain this phenomenon to me.请向我解释这个现象。
this.testObject = { a: 1, b: { a: 3, b: { a: 78, b: null } } }; let g = this.testObject; while (gb) { g = gb; } gb = { a: 79, b: null }; console.log(this.testObject); // { a: 1, b: { a: 3, b: { a: 78, b: { a: 79, b: null } } } }
Now I decided to stick with this.testObject
and removed g
:现在我决定坚持使用this.testObject
并删除g
:
this.testObject = { a: 1, b: { a: 3, b: { a: 78, b: null } } }; while (this.testObject.b) { this.testObject = this.testObject.b; } this.testObject.b = { a: 79, b: null }; console.log(this.testObject); // {a": 78,b": {a": 79,b": null}
What's going on?这是怎么回事? How is my assignment of g
affecting this object this way?我的g
分配如何以这种方式影响这个 object?
In first snippet, if I did g=gb
then I am basically assigning a new value to g
.在第一个片段中,如果我做了g=gb
那么我基本上是在为g
分配一个新值。 However if I explicitly do this, then result isn't same?但是,如果我明确地这样做,那么结果不一样吗?
this.testObject = {a:1, b:{a:3,b:{a:78, b:null}}}; let g = this.testObject; while(gb){ g = {a:7777, b:null}; } gb={a:79, b:null}; this.testObject; // {a": 1,b": {a": 3,b": {a": 78,b": null}
I'm guessing you're expecting the two snippets to produce the same result.我猜你希望这两个片段产生相同的结果。 But the code doesn't do the same thing.但是代码并没有做同样的事情。
You're using g
as a sort of reference in the first example.您在第一个示例中使用g
作为一种参考。 This means that every time you set g
in the while loop, you're not affecting this.testObject
in any way since you're just "moving" the reference.这意味着每次在 while 循环中设置g
时,您都不会以任何方式影响this.testObject
,因为您只是在“移动”引用。 But it is still a reference, so altering anything inside the object that g
is referencing, you will also set it in this.testObject
, thus producing the result you get in the first example.但它仍然是一个引用,因此更改g
引用的 object 中的任何内容,您还将在this.testObject
中设置它,从而产生您在第一个示例中获得的结果。
In the second example, you're replacing this.testObject
each time in the while loop.在第二个示例中,您每次都在 while 循环中替换this.testObject
。 So setting this.testObject = this.testObject.b
will remove the outer object, resulting in this.testObject
going from:因此设置this.testObject = this.testObject.b
将移除外部 object,导致this.testObject
来自:
{ a: 1, b: { a: 3, b: { a: 78, b: null } } }
To:至:
{ a: 3, b: { a: 78, b: null } }
And since this.testObject.b
isn't null, you're repeating this again, making this.testObject
become:并且由于this.testObject.b
不是 null,因此您再次重复此操作,使this.testObject
变为:
{ a: 78, b: null }
Lastly, you're setting this.testObject.b
to a new object, overwriting the previous null value.最后,将this.testObject.b
设置为新的 object,覆盖之前的 null 值。 This results in the output you get in the second example.这将导致您在第二个示例中获得 output。
Usually when answering these question people draw boxes and arrows between them to indicate pointers, but I'm lazy, so let's consider a simple virtual machine instead.通常在回答这些问题时,人们会在它们之间绘制方框和箭头来表示指针,但我很懒,所以让我们考虑一个简单的虚拟机。 This machine can operate on memory blocks and their numbers (aka "pointers").这台机器可以在 memory 块及其编号(又名“指针”)上运行。 There are three operations:共有三种操作:
$number
) allocate:分配一个 memory 块,用一些数据初始化它并返回一个指向它的指针(表示为$number
)In terms of this machine, your first snippet would translate to this:就这台机器而言,您的第一个片段将转换为:
// this.testObject = { a: 1, b: { a: 3, b: { a: 78, b: null } } };
allocate: $1 = {a: 78, b: null}
allocate: $2 = {a: 3, b: $1}
allocate: $3 = {a: 1, b: $2}
write: this.testObject = $3
// let g = this.testObject;
write: g = $3
// while (g.b) { g = g.b; }
write: g = $3.b // first pass, g is now $2
write: g = $2.b // second pass, g is now $1
// g.b = { a: 79, b: null }
allocate: $4 = { a: 79, b: null }
write: $1.b = $4
// console.log(this.testObject);
read: $3 ==> {a: 1, b: $2}
read: $2 ==> {a: 3, b: $1}
read: $1 ==> {a: 78, b: $4}
read: $4 ==> { a: 79, b: null }
Basically, each {...}
is an "allocate" operation, each assignment is a "write" and console.logs
are "reads".基本上,每个{...}
都是一个“分配”操作,每个分配都是一个“写”, console.logs
是“读”。 Try to "translate" your other snippets to this machine and you'll see what's actually going on.尝试将你的其他片段“翻译”到这台机器上,你会看到实际发生了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.