繁体   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