How to copy an Array
Value types are trivial to copy, just assign them to a new variable:
var a = 2;
var b = a;
a = 5;
// a = 5
// b = 2
This approach works for Numbers, Strings, Booleans, Null, Undefined, and Symbols.
But Arrays are referenced types; therefore simple assignment does not duplicate the array:
var a = [2];
var b = a;
a[0] = 5;
// a = [5]
// b = [5]
How to copy an Array then?
Shallow copy
Use .concat()
, .slice()
, or [...arr]
(or one of the several other approaches):
var a = [2];
var b = [...a];
a[0] = 5;
// a = [5]
// b = [2]
But this produces a shallow copy so that Arrays deeper in the hierarchy does not get cloned:
var a = [[2]];
var b = [...a];
a[0][0] = 5;
// a = [[5]]
// b = [[5]]
Only the first level gets cloned, that's why it's called "shallow".
Deep copy
For simple cases, where only Arrays, Objects, and primitive data types are used, JSON.parse(JSON.stringify(arr))
will do:
var a = [[2]];
var b = JSON.parse(JSON.stringify(a));
a[0][0] = 5;
// a = [[5]]
// b = [[2]]
But there are several cases this approach cannot handle. The most notable is that circular references are impossible to be stringified:
var a = [2];
var a2 = [a];
a[0] = a2;
var b = JSON.parse(JSON.stringify(a)) // Error
Unfortunately, for a deep cloning function that handles more edge cases, you'll need to use a library. There are several to choose from:
- clone
- Lodash's clone
- And many others
For example, the clone library has no problems copying a structure with circular references:
var a = [2];
var a2 = [a];
a[0] = a2;
var b = clone(a);
Do these libraries provide a bulletproof deep clone function?
Unfortunately, not. For example, they usually can not clone DOM nodes, and they have varying support for other edge cases. Some support all RegExp properties, some support Symbols, some support prototype chains, but there always will be some that they do not (or can not) support.
But they cover most real-world use cases, and they are your best bet for cloning Arrays.
Try it
References
- https://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript
- https://lodash.com/docs/4.17.4#clone
- https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
- https://github.com/pvorb/clone
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures