web-dev-qa-db-fra.com

La modification d'une copie d'un objet JavaScript entraîne la modification de l'objet d'origine

Je copie myObj vers tempMyObj

var tempMyObj = myObj;

tempMyObj.entity est un tableau d'objets. Je modifie tempMyObj.entity en fonction de certaines conditions. Le problème est que si je modifie tempMyObj.entity le myObj.entity est également en cours de modification.

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

Il est clair que vous avez des idées fausses sur ce que la déclaration var tempMyObj = myObj; Est-ce que.

En JavaScript, les objets sont passés et attribués par référence (plus précisément la valeur d'une référence), donc tempMyObj et myObj sont tous deux des références au même objet.

Voici une illustration simplifiée qui peut vous aider à visualiser ce qui se passe

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

var tempMyObj = myObj;

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

Comme vous pouvez le voir après l'affectation, les deux références pointent vers le même objet.

Vous devez créer une copie si vous devez modifier l'un et non l'autre.

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

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

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

Ancienne réponse:

Voici quelques autres façons de créer une copie d'un objet

Puisque vous utilisez déjà jQuery:

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

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

Voir ici et ici

66
robbmj

Essayez d'utiliser la méthode create () comme indiqué ci-dessous.

var tempMyObj = Object.create(myObj);

Cela résoudra le problème.

4
Sandeep Mukherji

Essayez d'utiliser $. Extend () :

Si, toutefois, vous souhaitez conserver les deux objets d'origine, vous pouvez le faire en passant un objet vide comme cible:

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


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

Cela peut être très délicat, permettez-moi d'essayer de le dire de manière simple. Lorsque vous "copiez" une variable dans une autre variable en javascript, vous ne copiez pas réellement sa valeur de l'une à l'autre, vous assignez à la variable copiée, un référence à l'objet d'origine. Pour réellement faire une copie, vous devez créer un nouvel objet

La partie délicate est parce qu'il y a une différence entre attribuer une nouvelle valeur à la variable copiée et modifier sa valeur. Lorsque vous attribuez une nouvelle valeur à la variable de copie, vous obtenez débarrasser de la référence et affecter la nouvelle valeur à la copie, cependant, si vous seulement modifiez la valeur de la copie (sans assigner une nouvelle valeur), vous modifiez la copie et l'original.

J'espère que l'exemple aide!

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