Javascript 操纵数组中的对象会更改数组外的对象吗?

Javascript 操纵数组中的对象会更改数组外的对象吗?,javascript,arrays,node.js,Javascript,Arrays,Node.js,我不明白为什么会发生这种行为。假设我定义了一个对象,并将该对象的3个元素组成一个数组。如果修改数组中的对象,会影响该对象的所有实例吗?有人能解释一下为什么会这样吗?另外,如何创建一个包含对象独立“副本”的数组,以获得所需的行为?谢谢 范例 testObject = {"value1":"a","value2":"b"}; objArray = []; for(i=0; i < 3; i++){ var newobj = testObject; //make a new testObj

我不明白为什么会发生这种行为。假设我定义了一个对象,并将该对象的3个元素组成一个数组。如果修改数组中的对象,会影响该对象的所有实例吗?有人能解释一下为什么会这样吗?另外,如何创建一个包含对象独立“副本”的数组,以获得所需的行为?谢谢

范例

testObject = {"value1":"a","value2":"b"};
objArray = [];
for(i=0; i < 3; i++){
   var newobj = testObject; //make a new testObject
   objArray.push(newobj); //push new object to array
   }
delete objArray[0].value2 // Desired, delete value 2 ONLY from array object 0
objArray[2].value2 //Undefined? Why is value2 missing from object 2 
testObject.value2 //Undefined? Why is value2 missing from original object?
testObject={“value1”:“a”,“value2”:“b”};
objArray=[];
对于(i=0;i<3;i++){
var newobj=testObject;//创建一个新的testObject
objArray.push(newobj);//将新对象推送到数组
}
删除objArray[0]。值2//如果需要,请仅从数组对象0中删除值2
objArray[2]。值2//未定义?为什么对象2中缺少value2
testObject.value2//是否未定义?为什么原始对象中缺少value2?
与原语(字符串、数字、布尔、空符号、未定义)相反,javascript中的对象通过
引用传递。变量用作这些对象的占位符/指针。要创建对象的副本而不存在变异风险,请使用(兼容性除外):

或者传统上,,传递空对象文本以避免原始
测试对象的易变性:

const newObject = Object.assign({}, testObject);
至于深度克隆,MDN建议结合使用
JSON.parse()
JSON.stringify()
。例如:

const testObject = { value: "a", other: { value2: b } }; 

const newObject = JSON.parse(JSON.stringify(testObject));
与原语(字符串、数字、布尔、空符号、未定义)相反,javascript中的对象通过
引用传递。变量用作这些对象的占位符/指针。要创建对象的副本而不存在变异风险,请使用(兼容性除外):

或者传统上,,传递空对象文本以避免原始
测试对象的易变性:

const newObject = Object.assign({}, testObject);
至于深度克隆,MDN建议结合使用
JSON.parse()
JSON.stringify()
。例如:

const testObject = { value: "a", other: { value2: b } }; 

const newObject = JSON.parse(JSON.stringify(testObject));

在循环中一次又一次地推送同一对象的引用

for(i=0; i < 3; i++){
   var newobj = testObject; //no new object,same object's reference again 
   objArray.push(newobj); //push new object to array
   }
(i=0;i<3;i++)的
{
var newobj=testObject;//没有新对象,再次引用同一对象
objArray.push(newobj);//将新对象推送到数组
}
应该是

for(i=0; i < 3; i++){
   var newobj =  {"value1":"a","value2":"b"}; //make a new testObject
   objArray.push(newobj); //push new object to array
   }
(i=0;i<3;i++)的
{
var newobj={“value1”:“a”,“value2”:“b”};//创建一个新的testObject
objArray.push(newobj);//将新对象推送到数组
}

您在循环中一次又一次地推送同一对象的引用

for(i=0; i < 3; i++){
   var newobj = testObject; //no new object,same object's reference again 
   objArray.push(newobj); //push new object to array
   }
(i=0;i<3;i++)的
{
var newobj=testObject;//没有新对象,再次引用同一对象
objArray.push(newobj);//将新对象推送到数组
}
应该是

for(i=0; i < 3; i++){
   var newobj =  {"value1":"a","value2":"b"}; //make a new testObject
   objArray.push(newobj); //push new object to array
   }
(i=0;i<3;i++)的
{
var newobj={“value1”:“a”,“value2”:“b”};//创建一个新的testObject
objArray.push(newobj);//将新对象推送到数组
}

在JavaScript中创建对象时,实际上是在创建对该对象的引用。您可以将其存储在一个变量中并传递给其他人。。。可能会将其附加到数组中。当您对对象引用执行操作时,它会找到引用指向的原始对象并对其进行更新。因此,当您使用
.push
时,它不是创建新对象,而是简单地将引用推送到该对象。如果您在一个位置更新它,它将在另一个位置以及您指定该引用的任何其他位置更新它

将对象复制到新对象通常称为克隆。有很多不同的方法可以在JavaScript中克隆对象,结果也各不相同

您可以使用另一个答案所建议的
var newobj={…testObject}
。这个扩展操作符实质上复制了
testObject
的属性,并创建了一个新对象(用外部
{
}
声明)。然后将对该新对象的引用指定给
newobj
。你可以这样想:

var newobj = {
  value1: testObject.value1,
  value2: testObject.value2,
};
但是,您应该记住,这只提供了一个克隆级别。也就是说,如果对象包含其他对象,则对该对象的引用将被指定为属性,而不是该对象的克隆。例如:假设您有:

var testObject = { obj: { a: "b" } };
var newobj = { ...testObject };
delete testObject.obj.a;
console.log(newobj); // { obj: {} }
为了解决这个问题,您需要进行所谓的深度克隆,在JavaScript中,可以通过递归克隆对象属性来实现深度克隆。有很多方法可以做到这一点,包括像
lodash
这样的库或自制函数。例如:

最后,如果假定
testObject
类似于从中派生其他
newobj
的对象模板或初始状态,那么使用函数可能更有意义:

function newObjFactory() {
  return {
    value1: "a",
    value2: "b",
  };
}

然后您可以执行
var newobj=newObjFactory()
,每次都会得到一个新对象,因为每次调用函数时都会创建一个新对象,并且
返回
ed.

在JavaScript中创建对象时,实际上是在创建对该对象的引用。您可以将其存储在一个变量中并传递给其他人。。。可能会将其附加到数组中。当您对对象引用执行操作时,它会找到引用指向的原始对象并对其进行更新。因此,当您使用
.push
时,它不是创建新对象,而是简单地将引用推送到该对象。如果您在一个位置更新它,它将在另一个位置以及您指定该引用的任何其他位置更新它

将对象复制到新对象通常称为克隆。有很多不同的方法可以在JavaScript中克隆对象,结果也各不相同

您可以使用另一个答案所建议的
var newobj={…testObject}
。这个扩展操作符实质上复制了
testObject
的属性,并创建了一个新对象(用外部
{
}
声明)。然后将对该新对象的引用指定给
newobj
。你可以这样想:

var newobj = {
  value1: testObject.value1,
  value2: testObject.value2,
};
然而,你