繁体   English   中英

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

[英]Why does my JS object incorrectly change when not assigning the object to a variable?

请向我解释这个现象。

 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 } } } }

现在我决定坚持使用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}

这是怎么回事? 我的g分配如何以这种方式影响这个 object?

在第一个片段中,如果我做了g=gb那么我基本上是在为g分配一个新值。 但是,如果我明确地这样做,那么结果不一样吗?

 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}

我猜你希望这两个片段产生相同的结果。 但是代码并没有做同样的事情。

您在第一个示例中使用g作为一种参考。 这意味着每次在 while 循环中设置g时,您都不会以任何方式影响this.testObject ,因为您只是在“移动”引用。 但它仍然是一个引用,因此更改g引用的 object 中的任何内容,您还将在this.testObject中设置它,从而产生您在第一个示例中获得的结果。

在第二个示例中,您每次都在 while 循环中替换this.testObject 因此设置this.testObject = this.testObject.b将移除外部 object,导致this.testObject来自:

{ a: 1, b: { a: 3, b: { a: 78, b: null } } }

至:

{ a: 3, b: { a: 78, b: null } }

并且由于this.testObject.b不是 null,因此您再次重复此操作,使this.testObject变为:

{ a: 78, b: null }

最后,将this.testObject.b设置为新的 object,覆盖之前的 null 值。 这将导致您在第二个示例中获得 output。

通常在回答这些问题时,人们会在它们之间绘制方框和箭头来表示指针,但我很懒,所以让我们考虑一个简单的虚拟机。 这台机器可以在 memory 块及其编号(又名“指针”)上运行。 共有三种操作:

  • allocate:分配一个 memory 块,用一些数据初始化它并返回一个指向它的指针(表示为$number
  • write:将变量或属性的值设置为指针,使变量“指向”对应的memory块
  • 读取:给定一个指针,返回其 memory 块的内容

就这台机器而言,您的第一个片段将转换为:

// 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 }

基本上,每个{...}都是一个“分配”操作,每个分配都是一个“写”, console.logs是“读”。 尝试将你的其他片段“翻译”到这台机器上,你会看到实际发生了什么。

暂无
暂无

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

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