Изменение копии объекта JavaScript приводит к изменению исходного объекта

Я копирую myObj в tempMyObj

var tempMyObj = myObj;

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

Ответ 1

Понятно, что у вас есть некоторые заблуждения относительно того, что выражение var tempMyObj = myObj; делает.

В JavaScript объекты передаются и назначаются по ссылке (точнее значение ссылки), поэтому tempMyObj и myObj являются ссылками на один и тот же объект.

Вот упрощенная иллюстрация, которая может помочь вам визуализировать происходящее

// [Object1]<--------- myObj

var tempMyObj = myObj;

// [Object1]<--------- myObj
//         ^ 
//         |
//         ----------- tempMyObj

Как вы можете видеть после назначения, обе ссылки указывают на один и тот же объект.

Вам нужно создать копию, если вам нужно изменить ее, а не другую.

// [Object1]<--------- myObj

const tempMyObj = Object.assign({}, myObj);

// [Object1]<--------- myObj
// [Object2]<--------- tempMyObj

Старый ответ:

Вот несколько других способов создания копии объекта

Поскольку вы уже используете jQuery:

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

С ванильным 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);

Смотрите здесь и здесь

Ответ 2

Попробуйте использовать $. extend():

Если, однако, вы хотите сохранить оба исходных объекта, вы может сделать это, передав пустой объект в качестве цели:

var object = $.extend({}, object1, object2);


var tempMyObj = $.extend({}, myObj);

Ответ 3

Попробуйте использовать метод create(), как указано ниже.

var tempMyObj = Object.create(myObj);

Это решит проблему.

Ответ 4

Это может быть очень сложно, позвольте мне попытаться сделать это простым способом. Когда вы "копируете" одну переменную в другую переменную в javascript, вы фактически не копируете ее значение из одного в другое, вы назначаете скопированную переменную, ссылку на исходный объект. Чтобы сделать копию, вам необходимо создать новое использование объекта

Сложная часть состоит в том, что существует разница между назначением нового значения скопированной переменной и изменением ее значения. Когда вы назначаете новое значение переменной копирования, вы избавляетесь от ссылки и присваиваете новое значение копии, однако, если вы изменяете только значение копии (без присвоения нового значения), вы изменяете копия и оригинал.

Надеюсь, что этот пример поможет!

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

Ответ 5

объект глубокого клонирования с JSON.parse() и JSON.stringify

// Deep Clone
obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));

ссылка: эта статья