修改 JavaScript 对象的副本会导致原始对象发生更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29050004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Modifying a copy of a JavaScript object is causing the original object to change
提问by Vallabha
I am copying myObjto tempMyObj
我复制myObj到tempMyObj
var tempMyObj = myObj;
tempMyObj.entityis an array of objects. I am modifying tempMyObj.entitybased on some conditions. The problem is if I modify tempMyObj.entitythe myObj.entityis also getting modified.
tempMyObj.entity是一个对象数组。我正在tempMyObj.entity根据某些条件进行修改。问题是,如果我修改tempMyObj.entity,myObj.entity也会被修改。
for (j = 0; j < myObj.length; j++) {
if (myObj[j].type == "TableShape") {
var dupEntites = new Array();
for (i = 0; i < myObj[j].entities.length; i++) {
if (chk.value != myObj[j].entities[i].id) {
var obj = {};
obj.text = myObj[j].entities[i].text;
obj.id = myObj[j].entities[i].id;
dupEntites.push(obj);
}
else {
if (chk.checked)
{
var obj = {};
obj.text = myObj[j].entities[i].text;
obj.id = myObj[j].entities[i].id;
dupEntites.push(obj);
}
}
}
tempMyObj[j].entities = dupEntites;
}
}
回答by robbmj
It is clear that you have some misconceptions of what the statement var tempMyObj = myObj;does.
很明显,您对语句的var tempMyObj = myObj;作用有一些误解。
In JavaScript objects are passed and assigned by reference (more accurately the value of a reference), so tempMyObjand myObjare both references to the same object.
在 JavaScript 中,对象是通过引用传递和分配的(更准确地说是引用的值),因此tempMyObj和myObj都是对同一对象的引用。
Here is a simplified illustration that may help you visualize what is happening
这是一个简化的插图,可以帮助您想象正在发生的事情
// [Object1]<--------- myObj
var tempMyObj = myObj;
// [Object1]<--------- myObj
// ^
// |
// ----------- tempMyObj
As you can see after the assignment, both references are pointing to the same object.
正如你在赋值之后看到的,两个引用都指向同一个对象。
You need to create a copyif you need to modify one and not the other.
如果您需要修改一个而不是另一个,则需要创建一个副本。
// [Object1]<--------- myObj
const tempMyObj = Object.assign({}, myObj);
// [Object1]<--------- myObj
// [Object2]<--------- tempMyObj
Old Answer:
旧答案:
Here are a couple of other ways of creating a copy of an object
以下是创建对象副本的其他几种方法
Since you are already using jQuery:
由于您已经在使用 jQuery:
var newObject = jQuery.extend(true, {}, myObj);
With vanilla JavaScript
使用原生 JavaScript
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
var newObject = clone(myObj);
回答by guest271314
Try using $.extend():
尝试使用$.extend():
If, however, you want to preserve both of the original objects, you can do so by passing an empty object as the target:
var object = $.extend({}, object1, object2);
但是,如果您想保留两个原始对象,则可以通过传递一个空对象作为目标来实现:
var object = $.extend({}, object1, object2);
var tempMyObj = $.extend({}, myObj);
回答by Sandeep Mukherji
Try using the create() method like as mentioned below.
尝试使用如下所述的 create() 方法。
var tempMyObj = Object.create(myObj);
This will solve the issue.
这将解决问题。
回答by Ahmed El Damasy
deep clone object with JSON.parse() and JSON.stringify
使用 JSON.parse() 和 JSON.stringify 深度克隆对象
// Deep Clone
obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));
refrence: this article
参考:这篇文章
回答by Marcio
This might be very tricky, let me try to put this in a simple way. When you "copy" one variable to another variable in javascript, you are not actually copying its value from one to another, you are assigning to the copied variable, a reference to the original object. To actually make a copy, you need to create a new object use
这可能非常棘手,让我尝试用简单的方式来说明。当您在 javascript 中将一个变量“复制”到另一个变量时,您实际上并不是在将其值从一个变量复制到另一个变量,而是将其分配给复制的变量,即对原始对象的引用。要实际制作副本,您需要创建一个新对象使用
The tricky part is because there's a difference between assigning a new value to the copied variable and modify its value.When you assign a new valueto the copy variable, you are getting rid of the reference and assigning the new value to the copy, however, if you only modify the valueof the copy (without assigning a new value), you are modifying the copy and the original.
棘手的部分是因为为复制的变量分配新值和修改其值之间存在差异。当您为 copy 变量分配新值时,您正在摆脱引用并将新值分配给副本,但是,如果您只修改副本的值(不分配新值),您正在修改副本和原件。
Hope the example helps!
希望例子有帮助!
let original = "Apple";
let copy1 = copy2 = original;
copy1 = "Banana";
copy2 = "John";
console.log("ASSIGNING a new value to a copied variable only changes the copy. The ogirinal variable doesn't change");
console.log(original); // Apple
console.log(copy1); // Banana
console.log(copy2); // John
//----------------------------
original = { "fruit" : "Apple" };
copy1 = copy2 = original;
copy1 = {"animal" : "Dog"};
copy2 = "John";
console.log("\n ASSIGNING a new value to a copied variable only changes the copy. The ogirinal variable doesn't change");
console.log(original); //{ fruit: 'Apple' }
console.log(copy1); // { animal: 'Dog' }
console.log(copy2); // John */
//----------------------------
// HERE'S THE TRICK!!!!!!!
original = { "fruit" : "Apple" };
let real_copy = {};
Object.assign(real_copy, original);
copy1 = copy2 = original;
copy1["fruit"] = "Banana"; // we're not assiging a new value to the variable, we're only MODIFYING it, so it changes the copy and the original!!!!
copy2 = "John";
console.log("\n MODIFY the variable without assigning a new value to it, also changes the original variable")
console.log(original); //{ fruit: 'Banana' } <====== Ops!!!!!!
console.log(copy1); // { fruit: 'Banana' }
console.log(copy2); // John
console.log(real_copy); // { fruit: 'Apple' } <======== real copy!

