簡體   English   中英

javascript為什么2個不同的對象引用/使用相同的數組?

[英]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成為新對象的原型。 所有方法和屬性均取自原型鏈 ,除非該對象通過擁有自己的具有相同名稱的屬性來覆蓋它們。 由於arrOBJ的屬性,因此所有對象都會更新,並顯示相同的數組。

建議的解決方案

您可以使用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)。您要在原型上實例化一個數組,而沒有意識到更改該數組會修改所有實例。

obj1obj2最初具有與OBJ原型相同的idarr的引用。

僅當obj1.id / obj2.id更改時, obj1 / obj2才擁有自己的新ID副本,否則它們引用的是OBJ原型的相同ID

現在,此行為僅適用於原始類型。 對於非原始類型,即Array, obj1obj2始終引用OBJ原型的相同arr

暫無
暫無

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

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