[英]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.