修改 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:48:06  来源:igfitidea点击:

Modifying a copy of a JavaScript object is causing the original object to change

javascriptobjectcopy

提问by Vallabha

I am copying myObjto tempMyObj

我复制myObjtempMyObj

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.entitymyObj.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 中,对象是通过引用传递和分配的(更准确地说是引用的值),因此tempMyObjmyObj都是对同一对象的引用。

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);

See hereand here

看到这里这里

回答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!