JavaScript provides several different types of arrays (at least five types).
var type1 = ['a', 'b']; // String literal array
var type2 = [1, 2]; // Number literal array
var type3 = [['a'], ['b']]; // Array literal array
var type4 = [{a: 'a'} , {b: 'b'}]; // Object literal array
var type5 = [{a: function () {}}, {b: function () {}}]; // Object array
Note: The word "literal" is important. Strings, numbers, arrays, and objects may also be created as prototype objects. For example:
/* Seen in type1 array */ var stringLiteral = 'stringLiteral';
/* Seen in type5 array */ var stringObject = new String('stringLiteral');
/* Seen in type1 array */ var numberLiteral = 1;
/* Seen in type5 array */ var numberObject = new Number(1);
// etc.
Depending on the array-type (type1, type2, etc.), various techniques can be used to deep-copy an array. For example:
myArray.splice(0);
myArray.slice();
myArray.concat();
JSON.parse(JSON.stringify(myArray));
$.extend(true, [], myArray); // jQuery
_.extend(myArray); // underscore
_.cloneDeep(myArray); // lo-dash
However, most techniques won't deep-copy all array-types.
Deep-copy support for various techniques (by array-type)

- The
myArray.splice(0)
, myArray.slice()
, and myArray.concat()
techniques can be used to deep copy an Array of String literals, and an Array of Number literals; where Slice is faster in performance than Concat. http://jsperf.com/duplicate-array-slice-vs-concat/3.
- The
JSON.parse(JSON.stringify(myArray))
technique can be used to deep copy any Array of Literals (type1, type2, type3, and type4) - but not an Array of Objects (type5).
- The jQuery
$.extend(myArray)
technique can be used to deep-copy all array-types. Libraries like Underscore and Lo-dash offer similar deep-copy functions to jQuery $.extend()
, yet have slower performance. More surprisingly, $.extend()
is faster in performance than the JSON.parse(JSON.stringify(myArray))
technique http://jsperf.com/js-deep-copy/2.
Deep-copy any array-type (without a third-party library):
And for those developers that shy away from third-party libraries (like jQuery), you can use the following custom function; which has faster performance than $.extend, and deep-copies all array-types. Warning! In NodeJS this solution is problematic; any null
objects in the deep copied array will be converted to empty object literals {}
.
function copy(o) {
var output, v, key;
output = Array.isArray(o) ? [] : {};
for (key in o) {
v = o[key];
output[key] = (typeof v === "object") ? copy(v) : v;
}
return output;
}
So to answer the question...
Question
var arr1 = ['a','b','c'];
var arr2 = arr1;
I realized that arr2 refers to the same array as arr1, rather than a
new, independent array. How can I copy the array to get two
independent arrays?
Answer
Because this is a String Literal Array (type1), you can use any of the various techniques, where .slice()
provides the fastest performance.
arr2 = arr1.slice(); // Fastest performance for String Literal Array
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = $.extend(true, [], arr1); // jQuery.js needed
arr2 = _.extend(arr1); // Underscore.js needed
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = copy(arr1); // Custom-function needed - as provided above
slice
andsplice
operations and new spread operator andArray.from
have much slower implementation. Look at perfjs.fnfo – Pencroff Sep 16 at 13:32