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

- Splice, Slice, and Concat can be used to deep copy an Array of String literals, and an Array of Number literals; where Slice has better performance than Concat. http://jsperf.com/duplicate-array-slice-vs-concat/3.
- JSON.parse(JSON.stringify()) can be used to deep copy an Array of String literals, an Array of Number literals, an Array of Arrays, and an Array of Object Literals - but not an Array of Prototype Objects.
- jQuery $.extend() can be used to deep-copy any array-type. Other libraries like Underscore and Lo-dash offer similar deep-copy functions, however they provide slower performance as well. More surprisingly, $.extend also has better performance than JSON.parse(JSON.stringify()) 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 out, v, key;
out = Array.isArray(o) ? [] : {};
for (key in o) {
v = o[key];
out[key] = (typeof v === "object") ? copy(v) : v;
}
return out;
}
So to answer the 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?
Because this is an array of string literals, it's a type1 array, and therefore you can use any of the various deep-copy techniques, where slice provides the fastest performance.
// Any of these techniques will deep-copy an Array of String literals
arr2 = arr1.slice();
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