# Fastest way to duplicate an array in JavaScript – slice vs. ‘for’ loop

## The Question :

664 people think this question is useful

In order to duplicate an array in JavaScript: which of the following is faster to use?

###Slice method

var dup_array = original_array.slice();



###For loop

for(var i = 0, len = original_array.length; i < len; ++i)
dup_array[i] = original_array[i];



I know both ways do only a shallow copy: if original_array contains references to objects, objects won’t be cloned, but only the references will be copied, and therefore both arrays will have references to the same objects. But this is not the point of this question.

806 people think this answer is useful

There are at least 6 (!) ways to clone an array:

• loop
• slice
• Array.from()
• concat
• map A.map(function(e){return e;});

There has been a huuuge BENCHMARKS thread, providing following information:

• for blink browsers slice() is the fastest method, concat() is a bit slower, and while loop is 2.4x slower.

• for other browsers while loop is the fastest method, since those browsers don’t have internal optimizations for slice and concat.

This remains true in Jul 2016.

Below are simple scripts that you can copy-paste into your browser’s console and run several times to see the picture. They output milliseconds, lower is better.

while loop

n = 1000*1000;
start = + new Date();
a = Array(n);
b = Array(n);
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);



slice

n = 1000*1000;
start = + new Date();
a = Array(n);
b = a.slice();
console.log(new Date() - start);



Please note that these methods will clone the Array object itself, array contents however are copied by reference and are not deep cloned.

origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true



258 people think this answer is useful

Technically slice is the fastest way. However, it is even faster if you add the 0 begin index.

myArray.slice(0);



is faster than

myArray.slice();



http://jsperf.com/cloning-arrays/3

146 people think this answer is useful

arr2 = [...arr1];



43 people think this answer is useful

Easiest way to deep clone Array or Object:

var dup_array = JSON.parse(JSON.stringify(original_array))



32 people think this answer is useful
var cloned_array = [].concat(target_array);



26 people think this answer is useful

I put together a quick demo: http://jsbin.com/agugo3/edit

My results on Internet Explorer 8 are 156, 782, and 750, which would indicate slice is much faster in this case.

22 people think this answer is useful

a.map(e => e) is another alternative for this job. As of today .map() is very fast (almost as fast as .slice(0)) in Firefox, but not in Chrome.

On the other hand, if an array is multi-dimensional, since arrays are objects and objects are reference types, none of the slice or concat methods will be a cure… So one proper way of cloning an array is an invention of Array.prototype.clone() as follows.

Array.prototype.clone = function(){
return this.map(e => Array.isArray(e) ? e.clone() : e);
};

var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
brr = arr.clone();
brr[4][2][1] = "two";
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));


21 people think this answer is useful

# 🏁 Fastest Way to Clone an Array

I made this very plain utility function to test the time that it takes to clone an array. It is not 100% reliable however it can give you a bulk idea as for how long it takes to clone an existing array:

function clone(fn) {
const arr = [...Array(1000000)];
console.time('timer');
fn(arr);
console.timeEnd('timer');
}



And tested different approach:

1)   5.79ms -> clone(arr => Object.values(arr));
2)   7.23ms -> clone(arr => [].concat(arr));
3)   9.13ms -> clone(arr => arr.slice());
4)  24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5)  30.02ms -> clone(arr => [...arr]);
6)  39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7)  99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));



UPDATE:

1. Tests were made back in 2018, so today most likely you’ll get different result with current browsers.
2. Out of all of those, the only way to deep clone an array is by using JSON.parse(JSON.stringify(arr)).

That said, do not use the above if your array might include functions as it will return null.
Thank you @GilEpshtain for this update.

8 people think this answer is useful

ECMAScript 2015 way with the Spread operator:

Basic examples:

var copyOfOldArray = [...oldArray]
var twoArraysBecomeOne = [...firstArray, ..seccondArray]



Try in the browser console:

var oldArray = [1, 2, 3]
var copyOfOldArray = [...oldArray]
console.log(oldArray)
console.log(copyOfOldArray)

var firstArray = [5, 6, 7]
var seccondArray = ["a", "b", "c"]
var twoArraysBecomOne = [...firstArray, ...seccondArray]
console.log(twoArraysBecomOne);



### References

7 people think this answer is useful

Take a look at: link. It’s not about speed, but comfort. Besides as you can see you can only use slice(0) on primitive types.

To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.

Example:

To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.

var oldArray = ["mip", "map", "mop"];
var newArray = oldArray.slice();



To copy or clone an object :

function cloneObject(source) {
for (i in source) {
if (typeof source[i] == 'source') {
this[i] = new cloneObject(source[i]);
}
else{
this[i] = source[i];
}
}
}

var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);



7 people think this answer is useful

As @Dan said “This answer becomes outdated fast. Use benchmarks to check the actual situation”, there is one specific answer from jsperf that has not had an answer for itself: while:

var i = a.length;
while(i--) { b[i] = a[i]; }



had 960,589 ops/sec with the runnerup a.concat() at 578,129 ops/sec, which is 60%.

This is the lastest Firefox (40) 64 bit.

@aleclarson created a new, more reliable benchmark.

6 people think this answer is useful

It depends on the browser. If you look in the blog post Array.prototype.slice vs manual array creation, there is a rough guide to performance of each:

Results:

6 people think this answer is useful

There is a much cleaner solution:

var srcArray = [1, 2, 3];
var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);



The length check is required, because the Array constructor behaves differently when it is called with exactly one argument.

6 people think this answer is useful

Remember .slice() won’t work for two-dimensional arrays. You’ll need a function like this:

function copy(array) {
return array.map(function(arr) {
return arr.slice();
});
}



5 people think this answer is useful

It depends on the length of the array. If the array length is <= 1,000,000, the slice and concat methods are taking approximately the same time. But when you give a wider range, the concat method wins.

For example, try this code:

var original_array = [];
for(var i = 0; i < 10000000; i ++) {
original_array.push( Math.floor(Math.random() * 1000000 + 1));
}

function a1() {
var dup = [];
var start = Date.now();
dup = original_array.slice();
var end = Date.now();
console.log('slice method takes ' + (end - start) + ' ms');
}

function a2() {
var dup = [];
var start = Date.now();
dup = original_array.concat([]);
var end = Date.now();
console.log('concat method takes ' + (end - start) + ' ms');
}

function a3() {
var dup = [];
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup.push(original_array[i]);
}
var end = Date.now();
console.log('for loop with push method takes ' + (end - start) + ' ms');
}

function a4() {
var dup = [];
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup[i] = original_array[i];
}
var end = Date.now();
console.log('for loop with = method takes ' + (end - start) + ' ms');
}

function a5() {
var dup = new Array(original_array.length)
var start = Date.now();
for(var i = 0; i < original_array.length; i ++) {
dup.push(original_array[i]);
}
var end = Date.now();
console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
}

a1();
a2();
a3();
a4();
a5();



If you set the length of original_array to 1,000,000, the slice method and concat method are taking approximately the same time (3-4 ms, depending on the random numbers).

If you set the length of original_array to 10,000,000, then the slice method takes over 60 ms and the concat method takes over 20 ms.

4 people think this answer is useful

In ES6, you can simply utilize the Spread syntax.

Example:

let arr = ['a', 'b', 'c'];
let arr2 = [...arr];



Please note that the spread operator generates a completely new array, so modifying one won’t affect the other.

Example:

arr2.push('d') // becomes ['a', 'b', 'c', 'd']
console.log(arr) // while arr retains its values ['a', 'b', 'c']



3 people think this answer is useful

A simple solution:

original = [1,2,3]
cloned = original.map(x=>x)



3 people think this answer is useful
        const arr = ['1', '2', '3'];

// Old way
const cloneArr = arr.slice();

// ES6 way
const cloneArrES6 = [...arr];

// But problem with 3rd approach is that if you are using muti-dimensional
// array, then only first level is copied

const nums = [
[1, 2],
[10],
];

const cloneNums = [...nums];

// Let's change the first item in the first nested item in our cloned array.

cloneNums[0][0] = '8';

console.log(cloneNums);
// [ [ '8', 2 ], [ 10 ], [ 300 ] ]

// NOOooo, the original is also affected
console.log(nums);
// [ [ '8', 2 ], [ 10 ], [ 300 ] ]



So, in order to avoid these scenarios to happen, use

        const arr = ['1', '2', '3'];

const cloneArr = Array.from(arr);



3 people think this answer is useful

Benchmark time!

function log(data) {
document.getElementById("log").textContent += data + "\n";
}

benchmark = (() => {
time_function = function(ms, f, num) {
var z = 0;
var t = new Date().getTime();
for (z = 0;
((new Date().getTime() - t) < ms); z++)
f(num);
return (z)
}

function clone1(arr) {
return arr.slice(0);
}

function clone2(arr) {
return [...arr]
}

function clone3(arr) {
return [].concat(arr);
}

Array.prototype.clone = function() {
return this.map(e => Array.isArray(e) ? e.clone() : e);
};

function clone4(arr) {
return arr.clone();
}

function benchmark() {
function compare(a, b) {
if (a[1] > b[1]) {
return -1;
}
if (a[1] < b[1]) {
return 1;
}
return 0;
}

funcs = [clone1, clone2, clone3, clone4];
results = [];
funcs.forEach((ff) => {
console.log("Benchmarking: " + ff.name);
var s = time_function(2500, ff, Array(1024));
results.push([ff, s]);
console.log("Score: " + s);

})
return results.sort(compare);
}
return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();

console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());

<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>


The benchmark will run for 10s since you click the button.

My results:

Chrome (V8 engine):

1. clone1 score: 100% *winner* (4110764)
2. clone3 score: 74.32% speed of winner. (3055225)
3. clone2 score: 30.75% speed of winner. (1264182)
4. clone4 score: 21.96% speed of winner. (902929)



Firefox (SpiderMonkey Engine):

1. clone1 score: 100% *winner* (8448353)
2. clone3 score: 16.44% speed of winner. (1389241)
3. clone4 score: 5.69% speed of winner. (481162)
4. clone2 score: 2.27% speed of winner. (192433)



Winner code:

function clone1(arr) {
return arr.slice(0);
}



Winner engine:

SpiderMonkey (Mozilla/Firefox)

1 people think this answer is useful

Fast ways to duplicate an array in JavaScript in Order:

#1: array1copy = [...array1];

#2: array1copy = array1.slice(0);

#3: array1copy = array1.slice();

If your array objects contain some JSON-non-serializable content (functions, Number.POSITIVE_INFINITY, etc.) better to use

array1copy = JSON.parse(JSON.stringify(array1))

1 people think this answer is useful

You can follow this code. Immutable way array clone. This is the perfect way to array cloning


const array = [1, 2, 3, 4]

const newArray = [...array]
newArray.push(6)
console.log(array)
console.log(newArray)



1 people think this answer is useful

If you want a REAL cloned object/array in JS with cloned references of all attributes and sub-objects:

export function clone(arr) {
return JSON.parse(JSON.stringify(arr))
}



ALL other operations do not create clones, because they just change the base address of the root element, not of the included objects.

Except you traverse recursive through the object-tree.

For a simple copy, these are OK. For storage address relevant operations I suggest (and in most all other cases, because this is fast!) to type convert into string and back in a complete new object.