简体   繁体   English

为什么不将 object 分配给变量时,我的 JS object 会错误地更改?

[英]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:共有三种操作:

  • allocate: allocate a memory block, initialize it with some data and return a pointer to it (denoted $number ) allocate:分配一个 memory 块,用一些数据初始化它并返回一个指向它的指针(表示为$number
  • write: set the value of a variable or a property to a pointer, so that the variable "points" to the corresponding memory block write:将变量或属性的值设置为指针,使变量“指向”对应的memory块
  • read: given a pointer, return the content of its memory block读取:给定一个指针,返回其 memory 块的内容

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.

相关问题 为什么在Dom对象中为自己分配变量会产生影响 - Why does assigning a variable to itself in a Dom Object make a difference 为什么我的属性分配不正确? - Why are my properties assigning incorrectly? 为什么给一个 object 赋值给另一个 object,然后重新赋值原来的 object 会改变这两个对象? - Why does assigning an object a value to that of another object, and then reassigning the original object change both objects? 当我们在变量中存储方法然后调用它时,为什么上下文对象会更改为全局窗口对象? - When we store a method in a variable and then call it, Why does the context object change to the global window object? 将requestAnimationFrame分配给对象变量时,类型错误 - Type Error when assigning requestAnimationFrame to object variable 在 JS 中分配给它时,有没有办法(或建议)返回 object? - Is there a way (or proposal) to return object when assigning to It, in JS? 为什么下面的代码在Node.js中没有改变我的object中的属性 - Why does the following code not change the property in my object in Node.js 为什么我在three.js中更改变量名称时,我的图形不呈现? - Why does my figure not render when I change the name of variable in three.js? 将对象分配给另一个变量 - Assigning an object to another variable 将arguments对象分配给变量 - Assigning the arguments object to a variable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM