簡體   English   中英

數組屬性上Object.create的怪異行為

[英]Weird behaviour with Object.create on array properties

使用Object.create()和原型對象創建新對象時,新對象似乎對數組屬性保留對原型的引用。

范例程式碼

var obj = { color: ['white'], cat: 'Kitty', state: {}};
obj2 = Object.create(obj);
obj2.color.push('blue');
obj2.color.push('red');
obj2.color.push('yellow');
obj2.cat = 'Fluffy';
obj2.state = {complete: false};
console.log('obj2 color = ' + JSON.stringify(obj2.color) + ', obj2.cat = ' + obj2.cat + ', state = ' + JSON.stringify(obj2.state));
console.log('obj color = ' + JSON.stringify(obj.color) + ', obj.cat = ' + obj.cat + ', state = ' + JSON.stringify(obj.state));

結果

obj2 color = ["white","blue","red","yellow"], obj2.cat = Fluffy, state = {"complete":false}
obj color = ["white","blue","red","yellow"], obj.cat = Kitty, state = {}

新obj2中的字符串屬性“ cat”具有預期的行為,並且與原型對象“ obj”中的該屬性無關。 與對象屬性“狀態”相同。

但是,在數組“顏色”上,當我更改數組時,它也在原型對象上也發生了變化!

這是用Java編寫的嗎? 對我而言,這是來自面向對象的背景,這完全是意外的。 我認為這沒有邏輯。 數組有什么不同?

如果像字符串這樣的值類型在行為上與對象屬性不同,但它們卻沒有(如本例所示),則我什至可以看到一些邏輯-數組的行為也有所不同。

分配給對象屬性:

obj.xyz = "hello world";

總是直接在目標對象上更新(如果需要,創建)屬性。

但是,將值推入數組並不構成“分配給對象屬性”。 請注意,鑒於您的代碼,

obj2.color = ["green"];

將直接在目標對象上創建一個新的“顏色”屬性。

在聲明中

obj2.color.push('blue');

在原型對象的查找操作中找到“顏色”屬性。 然后,通過該對象引用(對原型上“ color”屬性的引用),查找“ push”屬性。 最終可以在Array.prototype對象上找到。 然后將該值稱為函數。 在此過程中,沒有任何事情涉及更新“ obj2”上的屬性值。

原型上的“顏色”屬性是數組並不是特別特殊。 對於任何對象引用,您都會看到類似的效果。 考慮:

var proto = { obj: { a: 1, b: 2 } };
var obj2 = Object.create(proto);
obj2.obj.a = 3;

這將更改原型中的“ obj”對象。

最后應該指出的是, 通常原型是函數引用的來源,而不是簡單的值。

TLDR:設置對象的屬性可直接在該對象上設置它。 獲取屬性沿原型鏈上升。

 obj2.color

那得到原型的陣列。

除了Pointy解釋清楚的答案外 ,您還可以執行類似的操作來創建深度克隆的對象。

但是請注意,正如Pointy所說,這可能不適用於“所有”對象。

var new_obj = JSON.parse(JSON.stringify(old_obj));`

堆棧片段

 var obj = { color: ['white'], cat: 'Kitty', state: {}}; var obj2 = JSON.parse(JSON.stringify(obj)); obj2.color.push('blue'); obj2.color.push('red'); obj2.color.push('yellow'); obj2.cat = 'Fluffy'; obj2.state = {complete: false}; console.log('obj2 color = ' + JSON.stringify(obj2.color) + ', obj2.cat = ' + obj2.cat + ', state = ' + JSON.stringify(obj2.state)); console.log('obj color = ' + JSON.stringify(obj.color) + ', obj.cat = ' + obj.cat + ', state = ' + JSON.stringify(obj.state)); 

暫無
暫無

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

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