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.
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.
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...
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
How to Send a Cross-Domain Post Request Via JavaScript
When Should I Use Curly Braces For Es6 Import
Create and Save a File With JavaScript
Why Is Setstate in Reactjs Async Instead of Sync
Generate Random String/Characters in JavaScript
Format Number to Always Show 2 Decimal Places
How to Empty an Array in JavaScript
Listening For Variable Changes in JavaScript
How to Access React Instance (This) Inside Event Handler
Difference Between a Function Expression VS Declaration in JavaScript
Is It Bad Practice to Have a Constructor Function Return a Promise
Getting the Client'S Time Zone (And Offset) in JavaScript
How to Check If an Object Is an Array
What Is a Good Regular Expression to Match a Url
Chrome Extension Message Passing: Response Not Sent
Events Triggered by Dynamically Generated Element Are Not Captured by Event Handler