Изменение копии объекта 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));
ссылка: эта статья