簡體   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