But before that just keep one thing in mind that javascript objects are mutable by nature and stored as a reference. So when you assign the object to another variable, you’re just assigning the memory address of the object to that variable.
In this case your old and new object both will point to the same memory address. Any change in either object will be reflected in the other. So just assigning the one object to another will not really copies your object!!!
// Define object bar
var bar = {
x : 'Hi'
}
console.log(bar.x); //Hi
// Assign it to foo
var foo = bar;
console.log(foo.x); //Hi
//But
foo.x = 'Hello!! Im foo.';
console.log(foo.x); //Hello!! Im foo.
console.log(bar.x); //Hello!! Im foo.
bar.x = "Nice to meet you foo!!";
console.log(foo.x); //Nice to meet you foo!!
console.log(bar.x); //Nice to meet you foo!!
As you see in the above example, both foo and bar are reflecting the change done in either object.
But don’t we have 3 short and sweet method that you can use to copy an object.
Spread Syntax
or Object.assign
This one is shortest and simple method to copy/merge an object. See below example:
var obj = { foo: "foo", bar: "bar" };
var clonedObj = { ...obj };
// Object { foo: "foo", bar: "bar" }
The Object.assign()
method can be used to copy the values of all enumerable own properties from one or more source objects to a target object, and it will return the target object.
var obj = { foo: "foo", bar: "bar" };
var clonedObj = Object.assign({}, obj);
// Object { foo: "foo", bar: "bar" }
Using the spread syntax or Object. assign ()
is a standard way of copying an object in JavaScript. Both methodologies can be equivalently used to copy/merge the enumerable properties of an object to another object.
Problem with these two approaches is that it will just do the shallow copy. A shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. But if any of the fields of the object are references to other objects, just the reference addresses are copied, i.e., only the memory address is copied. Changing such reference field will be reflected in both objects. See the below example.
let obj = { a: 0 , b: { c: 0}};
let copySpread = {...obj};
let copyOA = Object.assign({}, obj);
console.log(JSON.stringify(obj)); // { a: 0, b: { c: 0}}
obj.a = 1;
console.log(JSON.stringify(obj)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(copySpread)); // { a: 0, b: { c: 0}}
console.log(JSON.stringify(copyOA)); // { a: 0, b: { c: 0}}
copySpread.a = 2;
console.log(JSON.stringify(obj)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(copySpread)); // { a: 2, b: { c: 0}}
console.log(JSON.stringify(copyOA)); // { a: 0, b: { c: 0}}
copyOA.a = 3;
console.log(JSON.stringify(obj)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(copySpread)); // { a: 2, b: { c: 0}}
console.log(JSON.stringify(copyOA)); // { a: 3, b: { c: 0}}
obj.b.c = 4;
console.log(JSON.stringify(obj)); // { a: 1, b: { c: 4}}
console.log(JSON.stringify(copySpread)); // { a: 2, b: { c: 4}}
console.log(JSON.stringify(copyOA)); // { a: 3, b: { c: 4}}
So these two methods are short and very useful one, but it won’t work out when you’re having nested object in your object to be copied.
JSON.stringify
and JSON.parse
A deep copy occurs when an object is copied along with the objects to which it refers. This can be done easily by using the combination of JSON.stringify
and JSON.parse
to create deep copy.
In this method we are first JSON.stringify() the json object and again parse it to get json object back. The JSON.parse() method parses a JSON string and constructs the JavaScript value or object described by the string. These new object fields will have their own memory address and will be independent of deeply nested object fields
See below example, deepClone object won’t have any effect if the main source object obj is modified and vice-versa.
// Deep Clone
obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));
obj.a = 5;
obj.b.c = 5;
console.log(JSON.stringify(obj)); // { a: 5, b: { c: 5}}
console.log(JSON.stringify(deepClone)); // { a: 0, b: { c: 0}}
deepClone.a = 6;
deepClone.b.c = 6;
console.log(JSON.stringify(obj)); // { a: 5, b: { c: 5}}
console.log(JSON.stringify(deepClone)); // { a: 6, b: { c: 6}}
or you can write your own function to do the deep copy/cloning.
Thanks for reading
#javascript #es6