Modifying a Copy of a JavaScript Object Is Causing the Original Object to Change

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

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

Why reassigning of an object have different value?

Objects are stored by reference and not by value.

let a = { name:'Pete' };

The line above creates an object in memory and variable a stores a reference to this object.

let b = a

When you make b equal to a, the variable b also stores the reference to the same object.

Now, whenever you make any changes to the object, it will reflect in both the variables a and b, because they both store the reference to the same object.

Sample Image

Now, when you do a = {}, this creates a new object (empty) in memory and variable a now stores a reference to this new object. But this would not change variable b because it stores a reference to the first object which hasn't changed.

Sample Image

Modifying a copy of an array is NOT causing the original object to change

  // Getting the list by state
let clientList = this.listsByState[state];
// if we are changing the page, we should empty the respective list
if (nextPage) {
clientList = [];
}

Are you expecting this line of code to also reset the array for this.listsByStatep[state]? It won't do that as you've assigned a new array to clientList and so the reference isn't the same (you can check this by doing console.log(clientList === this.listsByStatep[state]) before and after you assign the []). To do what you're looking for change it to this:

  // Getting the list by state
let clientList = this.listsByState[state];
// if we are changing the page, we should empty the respective list
if (nextPage) {
clientList.length = 0;
}

This doesn't destroy the reference and empties the array.

Why javascript object value is changed?

You are pointing y to the reference of x which itself is pointing to the object {a:1,b:2}.

So in memory it is:

x --> {a:1,b:2}

After you do y = x, it becomes:

y --> x --> {a:1,b:2}

Or to put it simply:

x --> {a:20,b:2}
^
|
y -------

Now when you do y.a = 20, since y and x are both pointing to the same object when properties of the object is changed through either of the references x or y the change will be reflected in both the references:

y --> {a:20,b:2}
^
|
x -------

That is why you get 20,2 when you get x.a.

How to change a property on an object without mutating it?

Two ways...

  1. You can use Object.assign:

    const a = { x: "Hi", y: "Test" }
    const b = Object.assign({}, a, { x: "Bye" });
    console.log("a:", a);
    console.log("b:", b);
    console.log("a === b:", a === b);

    Array value changes if object value is changed

    Arrays and Objects in javascript are pass by reference by default.

    If you want to avoid this behaviour, you could use Object.assign but that fails for deep copy of objects so you'll have to use JSON.parse(JSON.stringify(obj)) here,

    let newvalue = JSON.parse(JSON.stringify(original[i]));

    var original = [{
    a: 1,
    data: {
    b: 'before'
    }
    },
    {
    a: 2,
    data: {
    b: 'before'
    }
    }
    ];

    var arr1 = [];
    var arr2 = [];

    for (i = 0; i < original.length; i++) {
    let value = JSON.parse(JSON.stringify(original[i]));

    //pushed earlier
    arr1.push(value);

    let newvalue = JSON.parse(JSON.stringify(original[i]));
    if (newvalue.data.b == "before") {
    newvalue.data.b = "after";
    arr2.push(newvalue);
    }
    }

    console.log("ARRAY 1 ");
    console.log(arr1);
    console.log("ARRAY 2 ");
    console.log(arr2);


    Related Topics



Leave a reply



Submit