Deep copy in javascript
Deep Copy vs Reference Copy
In javascript, everytime you use = or pass a primitive to a function, you are doing deep copy, since whatever happends to it will never affect the origin one.
But things will be so different on objects:
1 | // deep copy on primitives |
Since objects passing by reference, so any changes on them will affect the actual data, so will be reflected to the origin ones.
Deep Copy on Objects
Most times, reference copy makes life easier. But sometimes, you actually need a deep copy of an object, then you may find several methods in this post :)
Object.assign
Object.assign is introduced by ES2015, now is supported by most modern browsers, of course, IE not included… but you can find a really handy polyfill for it from this link.
1 | // deep copy with Object.assign |
Of course, you can use Object.assign do a lot more than deep copy an object, but at least when you want to get some deep copies, this would be one of the easies way to do it.
JSON.parse and JSON.stringify
Considering Object.assign is not supported by ALL browsers, you may not want to use it. Then try JSON way:
1 | // deep copy with JSON.parse and JSON.stringify |
Cool, ha? But there is one condition that will give you error: CIRCULAR OBJECTS.
JSON.stringify can not convert circular objects to string, so it will break and thorw an error.
It does work on circular objects with Object.assign :)
slice and concat on arrays
If you want to deep copies on arrays, then you have two wonderful methods to use:
1 | // deep copy with slice |
The reason behind these two methods is because they both return new arrays instead of modifying origin ones.
Customized deep copy methods
Of course you can implement your own deep copy helper functions, actually several popular libs like jQuery, backbone, underscore, all have their own clone or extend methods to help you do deep copy.