Modifying a copy of a JavaScript object is causing

2019-01-02 18:45发布

I am copying myObj to tempMyObj

var tempMyObj = myObj;

tempMyObj.entity is an array of objects. I am modifying tempMyObj.entity based on some conditions. The problem is if I modify tempMyObj.entity the myObj.entity is also getting modified.

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

4条回答
时光乱了年华
2楼-- · 2019-01-02 19:17

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

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 value to the copy variable, you are getting rid of the reference and assigning the new value to the copy, however, if you only modify the value of the copy (without assigning a new value), you are modifying the copy and the original.

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!

查看更多
唯独是你
3楼-- · 2019-01-02 19:20

It is clear that you have some misconceptions of what the statement var tempMyObj = myObj; does.

In JavaScript objects are passed and assigned by reference (more accurately the value of a reference), so tempMyObj and myObj are both references to the same object.

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 copy if 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:

var newObject = jQuery.extend(true, {}, myObj);

With vanilla 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 here and here

查看更多
浪荡孟婆
4楼-- · 2019-01-02 19:23

Try using the create() method like as mentioned below.

var tempMyObj = Object.create(myObj);

This will solve the issue.

查看更多
大哥的爱人
5楼-- · 2019-01-02 19:30

Try using $.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 tempMyObj = $.extend({}, myObj);
查看更多
登录 后发表回答