[英]javascript why 2 different object are refering to/using same array?
我有一個對象定義,其中有一個數組。 當我實例化2個對象並訪問其成員時,兩個對象都寫入同一數組。 我期望每個對象都有自己的數組,而不共享同一數組。 對於對象的其他成員,它工作正常。 為什么會這樣?這樣做的正確方法是什么? 以下是示例代碼
//define simple object
var OBJ = {
id: 0,
arr: [0,0]
};
//instantiate objects
let obj1 = Object.create(OBJ);
let obj2 = Object.create(OBJ);
//change members value
obj1.id = 1;
obj1.arr[0]=1111;
obj2.id=2;
obj2.arr[1]=2222;
//verify changes
console.log(obj1.id); //id = 1 as expected
console.log(obj1.arr); //<--- expected [1111, 0000] NOT [1111, 2222]
console.log(obj2.id); //id = 2 as expected
console.log(obj2.arr); //<--- expected [0000, 2222] NOT [1111, 2222]
https://lodash.com/docs/4.17.5#cloneDeep
應該是您想要的,它將以遞歸方式復制所有內容
問題
當您使用Object.create()
從OBJ
創建新對象時, OBJ
成為新對象的原型。 所有方法和屬性均取自原型鏈 ,除非該對象通過擁有自己的具有相同名稱的屬性來覆蓋它們。 由於arr
是OBJ
的屬性,因此所有對象都會更新,並顯示相同的數組。
建議的解決方案
您可以使用Object.hasOwnProperty()
將arr
轉換為將檢查arr
是否為當前對象屬性的吸氣劑 ,如果不是,則克隆原型數組,然后將其返回。
//define simple object var OBJ = { id: 0, _arr: [0, 0], get arr() { if(!this.hasOwnProperty('_arr')) this._arr = [...this._arr]; return this._arr; } }; //instantiate objects let obj1 = Object.create(OBJ); let obj2 = Object.create(OBJ); //change members value obj1.id = 1; obj1.arr[0] = 1111; obj2.id = 2; obj2.arr[1] = 2222; //verify changes console.log(obj1.id); //id = 1 as expected console.log(obj1.arr); //<--- expected [1111, 0000] console.log(obj2.id); //id = 2 as expected console.log(obj2.arr); //<--- expected [0000, 2222]
您嘗試通過以下方法實現的目標:
function OBJ() {
this.id = 0;
this.arr = [0,0];
}
let obj1 = new OBJ();
let obj2 = new OBJ();
因為它為每個新創建的對象創建一個單獨的實例,即每個新創建的對象都有自己的id和arr副本。
您的方法適用於原始數據類型,但不適用於非原始數據類型(例如Array)。您要在原型上實例化一個數組,而沒有意識到更改該數組會修改所有實例。
obj1和obj2最初具有與OBJ原型相同的id和arr的引用。
僅當obj1.id / obj2.id更改時, obj1 / obj2才擁有自己的新ID副本,否則它們引用的是OBJ原型的相同ID 。
現在,此行為僅適用於原始類型。 對於非原始類型,即Array, obj1和obj2始終引用OBJ原型的相同arr 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.