[英]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”名稱! :)
......我遲到了? 以下是我對它的解釋(閱讀其他答案,這只是為了用視覺表示來支持這些答案):
a
( value:true
)。 b
為空對象a
指定另一個對象( value:true
)。 c
分配對象a
( value:true
)。 b
,因此ab
不再引用子對象( value:true
)。 a
最終表示a
。 因此,我們可以通過直觀表示輕松地看到子對象是如何被保留的:)
不,這不是JavaScript中的錯誤。
你在ac = ab
做的是你正在創建另一個指向同一個對象的鏈接,這意味着ab
和ac
都引用了同一個子對象{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
刪除。 該條目c
在a
仍然指向這個對象。 如果您嘗試刪除c.val
或abval
,您仍然可以看到效果級聯到另一個。
您正在嘗試做的事情,即解除分配數據並期望將其級聯,在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.