簡體   English   中英

通過引用復制到第二個屬性的對象即使在刪除原始屬性后仍然存在?

[英]Object copied to second property via reference persists even after original property deleted?

我認為對象是作為參考傳遞的。 但是當我刪除b ,它仍然存在於c 請看這個例子:

第一部分對我有意義,因為它通過引用傳遞:

var a = {b: {val:true}};

a.c = a.b;
a.b.val = 'rawr';

console.log(uneval(a)); // outputs: "({b:{val:"rawr"}, c:{val:"rawr"}})"

現在這部分對我來說沒有意義:

var a = {b: {val:true}};

a.c = a.b;
a.b.val = 'rawr';
delete a.b;

console.log(uneval(a)); // outputs: "({c:{val:"rawr"}})"

所以b屬性被刪除,但是c屬性將屬性保存到刪除之前引用的屬性。 這是javascript中的錯誤嗎?

編輯:感謝所有回復! 所以它不是一個bug,而且這種行為實際上非常好,它允許人們在保留對象的同時更改“key”/“property”名稱! :)

......我遲到了? 以下是我對它的解釋(閱讀其他答案,這只是為了用視覺表示來支持這些答案):

  1. 用另一個對象初始化空對象avalue:true )。

在此輸入圖像描述

  1. 使用屬性b為空對象a指定另一個對象( value:true )。

在此輸入圖像描述

  1. 使用引用同一對象的屬性c分配對象avalue:true )。

在此輸入圖像描述

  1. 刪除 b ,因此ab不再引用子對象( value:true )。

在此輸入圖像描述

  1. 主要對象a最終表示a

在此輸入圖像描述

因此,我們可以通過直觀表示輕松地看到子對象是如何被保留的:)

不,這不是JavaScript中的錯誤。

你在ac = ab做的是你正在創建另一個指向同一個對象的鏈接,這意味着abac都引用了同一個子對象{val: "rawr"}

當你delete ab ,你沒有刪除子對象,你只是從a刪除了ab屬性。 這意味着ac仍然會引用同一個對象。

如果你也要刪除ac屬性,那么子對象將會消失。

有兩點需要注意,首先,如在其他答案中所述,delete關鍵字僅刪除用於訪問該屬性的對象的屬性。

需要注意的第二件事是,JavaScript不會通過引用傳遞。 它總是作為值傳遞,值有時是引用。

例如:

var a = {
   someObject: {}
};
var someObject = a.someObject;

someObject = 'Test';

console.log(a.someObject); // outputs {}

在通過引用傳遞的語言中,這可能會導致錯誤,因為它通常意味着強大的變量類型。

那是因為:

delete運算符從對象中刪除屬性。 MDN刪除

對應於Object {val: true}條目 b將從a刪除。 該條目ca仍然指向這個對象。 如果您嘗試刪除c.valabval ,您仍然可以看到效果級聯到另一個。

您正在嘗試做的事情,即解除分配數據並期望將其級聯,在javascript中不會發生。 如果您有C ++背景,請考慮將所有javascript對象視為引用計數。 我可以刪除對它的引用(即'指向'此對象的條目),但我無法刪除對象本身。 這是javascript引擎的純粹特權。

有了這一行,你認為c指向b:

a.c = a.b;

但實際上c和b都指向{val:true}對象,所以如果刪除b,對象仍然存在。 你可以簡單地認為c和b都只是“標簽”粘在{val:true}對象上

不,這不是一個錯誤。

delete命令不會刪除該屬性引用的對象,它只刪除該屬性。 如果從其他位置引用該對象(在本例中為其他屬性),則該對象仍處於活動狀態。

這與兩個指向同一對象的變量相同,並更改一個變量的值:

var a = { val: true };
var b = a;
a = null;
console.log(b.val); // b still has a reference to the object

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM