678

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.

I'm asking only about speed.

Marco Demaio
  • 30,990
  • 33
  • 122
  • 155

23 Answers23

827

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

  • loop
  • slice
  • Array.from()
  • concat
  • spread operator (FASTEST)
  • 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
heretoinfinity
  • 1,024
  • 3
  • 9
  • 25
Dan
  • 48,995
  • 35
  • 110
  • 141
  • 1
    well done! This might be the best answer now. Would you be able to explain why the simple test done by lincolnk (it's the above answer http://stackoverflow.com/a/3978716/260080 ) gives out the opposite result, where `slice` is the faster than looping? I'm wondering if it's caused by the the type of elements in the array, in his test they were all numbers, in your are a mix of strings and objects. – Marco Demaio Dec 13 '13 at 16:00
  • Marco, you are quite right, storing data of one type speeds up an array. Google has written this somewhere, but you can always check it out http://jsperf.com/new-array-vs-splice-vs-slice/25 yourself However, the biggest difference makes the concrete engine realisation. Algorithms evolve from build to build. On the other hand we can predict evolution when knowing the engine architecture. @lincolnk's benchmarking results look similar to those http://jsperf.com/new-array-vs-splice-vs-slice/11, October '10 is somewhere close to Chrome 19 and FireFox 10. Oh, slice is shorter to type then concat :) – Dan Dec 13 '13 at 17:41
  • 53
    @cept0 no emotions, just benchmarks http://jsperf.com/new-array-vs-splice-vs-slice/31 – Dan Jun 13 '14 at 21:22
  • 2
    @Dan So what? Your test case results: Firefox 30 nightly is still ~230% faster than Chrome. Check the source code of V8 for `splice` and you'll be surprised (while...) – mate64 Jun 14 '14 at 06:22
  • 4
    [Sadly for short arrays the answer is vastly different](http://jsperf.com/new-array-vs-splice-vs-slice/72). For example cloning an array of listeners before calling each of them. Those arrays are often small, usually 1 element. – gman Feb 13 '15 at 02:05
  • I tested today 2015-05-04, the fastest method in Chrome 42 for Windows and for Android is .concat() – Jose Nobile May 05 '15 at 01:39
  • Congrats for benchmarking, demonstrated answer, nice work – tremendows Nov 27 '15 at 17:20
  • 1
    The charts in that benchmarks page show that at least since Chrome 34, the fastest method has been consistently the while loop pre-allocated. It beats all other methods on all browsers by a lot. – GetFree Feb 21 '16 at 10:39
  • jsperf is down. Shitty to refer to it, post the data next time directly here. – basickarl Jul 24 '16 at 20:50
  • 8
    You missed this method: `A.map(function(e){return e;});` – wcochran Sep 07 '16 at 18:25
  • At least as of 9.1.2 Safari has the slice/concat perf improvements, which are about 20x faster than while. – Christopher Swasey Oct 17 '16 at 18:11
  • 13
    You're writing about ***blink** browsers*. Isn't *blink* just a layout engine, mainly affecting HTML rendering, and thus unimportant? I thought we'd rather talk about V8, Spidermonkey and friends here. Just a thing that confused me. Enlighten me, if I'm wrong. – Neonit Oct 30 '16 at 09:58
  • 2
    **WARNING**: `.slice`, `spread`, `concat`, `Array.from` will not clone object in the array. Use a loop or a deep clone lib – BrunoLM Jan 06 '17 at 12:36
  • FYI: The 'while loop' version is slow as hell in IE. I would probably use `slice` to be consistent. – James Wilkins May 10 '17 at 03:16
  • I run these tests https://jsperf.com/new-array-vs-splice-vs-slice/152 on Chrome and `slice(0)` is the fastest one, but I think `Array.from()` looks cleaner even if it's 22% slower. –  Jan 06 '20 at 21:27
  • 2
    Best way for me is new_array = JSON.parse( JSON.stringify( old_array ) ). In this way all references are killed – Sergio Pisoni May 21 '20 at 09:36
  • You forgot type conversion! See my post below: function clone(arr) { return JSON.parse(JSON.stringify(arr))} ;) ALL other operations do not create clones, because you just change the base adress of the root element, not of the included objects. – nologin Aug 25 '20 at 21:35
268

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();

https://web.archive.org/web/20170824010701/https://jsperf.com/cloning-arrays/3

Makyen
  • 27,758
  • 11
  • 68
  • 106
KingKongFrog
  • 12,668
  • 17
  • 63
  • 111
  • And is `myArray.slice(0,myArray.length-1);` faster than `myArray.slice(0);` ? – jave.web May 17 '16 at 20:04
  • 4
    @jave.web you;ve just dropped last element of the array. Full copy is array.slice(0) or array.slice(0, array.length) – Marek Marczak Jan 04 '18 at 21:05
  • This is incorrect, at least on my machine and according to your own benchmarks. – John Leidegren Aug 13 '20 at 12:50
  • 3
    The link is dead. – kschiffer Oct 13 '20 at 11:55
  • https://jsben.ch/56xWo - sometimes, `slice()` is faster, sometimes `slice(0)`, both only marginally so (in Firefox 56 and latest Vivaldi, Chrome-based). But `slice(0, length)` is always noticeably slower (except that it's the fastest in Firefox 87). – f2d Apr 03 '21 at 17:46
152

what about es6 way?

arr2 = [...arr1];
Yukulélé
  • 11,464
  • 8
  • 52
  • 76
  • 26
    if converted with babel: `[].concat(_slice.call(arguments))` – CHAN Jul 27 '15 at 08:08
  • 1
    Not sure where `arguments` is coming from... I think your babel output is conflating a few different features. It's more likely to be `arr2 = [].concat(arr1)`. – Sterling Archer Sep 28 '16 at 05:54
  • 3
    @SterlingArcher `arr2 = [].conact(arr1)` is different from `arr2 = [...arr1]`. `[...arr1]` syntax will convert hole to `undefined`. For example, `arr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3`. – tsh Dec 28 '16 at 09:34
  • 1
    I tested this in my browser (Chrome 59.0.3071.115) against Dan's answer above. It was more than 10 times slower than .slice(). `n = 1000*1000; start = + new Date(); a = Array(n); b = [...a]; console.log(new Date() - start); // 168` – Harry Stevens Jul 08 '17 at 07:58
  • Simplest way. JS got this only in 2015... what a crappy language it was before (still far from decent). – stamster Dec 12 '17 at 12:05
  • 1
    Still will not clone something like this: `[{a: 'a', b: {c: 'c'}}]`. If `c`'s value is changed in the "duplicated" array, it will change in the original array, since it's just a referential copy, not a clone. – Neurotransmitter Feb 06 '19 at 09:59
  • 1
    As @TranslucentCloud mentioned, there is still the refernce. I just had a very very confusing time where I was [...baseSet, ...baseSet] to duplicate an array (for a Memory game) and I finally found I had a reference situation. I used lodash's `cloneDeep` to clone my array of objects. Thought to revisit this post and comment... Next time I'll read all comments first! – Neil Guy Lindberg Aug 08 '19 at 04:54
  • It doesn't really matter but as of March 2020, slice (150,936,056 ops/sec ±3.17%) is ~5x faster than the spread operator (34,565,713 ops/sec ±4.69%) in Node.js. – Wilson Biggs Mar 17 '20 at 22:37
43

Easiest way to deep clone Array or Object:

var dup_array = JSON.parse(JSON.stringify(original_array))
Vladimir Kharlampidi
  • 7,466
  • 2
  • 13
  • 11
  • 62
    Important note for beginners: because this depends upon JSON, this also inherits its limitations. Among other things, that means your array cannot contain `undefined` or any `function`s. Both of those will be converted to `null` for you during the `JSON.stringify` process. Other strategies, such as `(['cool','array']).slice()` will not change them but also do not deep clone objects within the array. So there is a tradeoff. – Seth Holladay Oct 07 '14 at 14:01
  • 28
    Very bad perf and don't work with special objects like DOM, date, regexp, function ... or prototyped objects. Don't support cyclic references. You should never use JSON for deep clone. – Yukulélé Dec 11 '15 at 17:57
  • 17
    worst possible way! Only use if for some issue all other doesn't work. It's slow, it's resources intense and it has all JSON limitations already mentioned in comments. Can't imagine how it got 25 up-votes. – Lukas Liesis Jul 24 '16 at 13:12
  • 3
    It deep copies arrays with primitives, and where properties are arrays with further primitives/arrays. For that it is ok. – Drenai Aug 06 '16 at 20:21
  • it's sure easy and very well known solution, but I wonder if it's **fast** – vsync Jan 01 '17 at 20:50
  • 5
    I tested this in my browser (Chrome 59.0.3071.115) against Dan's answer above. It was nearly 20 times slower than .slice(). `n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221 ` – Harry Stevens Jul 08 '17 at 08:02
  • Thanks, thats actually the only way I found to make a decent copy of my array :D – Ch3micaL Aug 08 '17 at 07:25
33
var cloned_array = [].concat(target_array);
Sajjad Shirazy
  • 1,999
  • 22
  • 22
  • 4
    Please explain what this does. – Jed Fox Oct 05 '16 at 16:54
  • 11
    While this code snippet may answer the question, it doesn't provide any context to explain how or why. Consider adding a sentence or two to explain your answer. – brandonscript Oct 05 '16 at 18:39
  • 36
    I hate this kind of comments. It's obvious what it does! – EscapeNetscape Oct 24 '16 at 18:21
  • 7
    A simple answer for a simple quetions, no big story to read. I like this kind of answers +1 – Achim Dec 09 '16 at 09:41
  • 20
    "I'm asking only about speed" - This answer gives no indication on speed. That is the main question being asked. brandonscript has a good point. More information is needed to consider this an answer. But if it were a simpler question, this would be an excellent answer. – TamusJRoyce Jan 09 '17 at 04:21
26

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
lincolnk
  • 10,642
  • 3
  • 36
  • 56
  • Don't forget the additional cost of the garbage collector if you have to do this very fast a lot. I was copying each neighbour array for each cell in my cellular automata using slice and it was much slower than reusing a previous array and copying the values. Chrome indicated about 40% of the total time was spent garbage collecting. – Drakarah Oct 11 '13 at 19:31
23

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.
Lior Elrom
  • 15,194
  • 15
  • 68
  • 84
  • 3
    I tried benchmarking your answer and I got very different results: http://jsben.ch/o5nLG – mesqueeb Feb 25 '19 at 01:02
  • @mesqueeb, the tests might change, depending on ur machine of course. However, feel free to update the answer with your test result. Nice work! – Lior Elrom Feb 25 '19 at 02:51
  • I like your answer a lot, however I try your test and get that `arr => arr.slice()` is the fastest. – Gil Epshtain Feb 26 '19 at 12:41
  • Thank you for running these tests @GilEpshtain! The result will change, depending on your machine. I noted that above the attached clone function. I think the main takeaway is that some methods are substantially faster than others. Especially when dealing with large data. Is that make sense? – Lior Elrom Feb 26 '19 at 13:38
  • 1
    @LiorElrom, your update isn't correct, due to the fact that methods aren't serializable. For example: `JSON.parse(JSON.stringify([function(){}]))` will output `[null]` – Gil Epshtain Feb 26 '19 at 14:15
  • Thanks @GilEpshtain, I didn't know that :) I'll make an update – Lior Elrom Feb 26 '19 at 14:21
  • 2
    Nice benchmark. I've tested this on my Mac in 2 browsers: Chrome Version 81.0.4044.113 and Safari Version 13.1 (15609.1.20.111.8) and fastest is spread operation: `[...arr]` with `4.653076171875ms` in Chrome and `8.565ms` in Safari. Second fast in Chrome is slice function `arr.slice()` with `6.162109375ms` and in Safari second is `[].concat(arr)` with `13.018ms`. – edufinn Apr 23 '20 at 08:57
  • I get very different results on different browsers by using the link from @mesqueeb's comment. On Chrome, I get that `[...arr]` is the fastest followed closely by `arr.slice()`, on Firefox, I get that `arr.slice()` is by far the fastest, and on iOS Safari `arr.slice()` is the fastest followed closely by both `[].concat(arr)` and `[...arr]`. So if we look at all these browsers combined, `arr.slice()` is the fastest. Also, the test results vary from one time to the next even on the same browser, but each time on each browser `arr.slice()` seems to be not too bad. – Donald Duck Jun 22 '20 at 16:56
22

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));
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Redu
  • 19,106
  • 4
  • 44
  • 59
  • Not bad, but unfortunately this doesn't work if you have Object in your array :\ JSON.parse(JSON.stringify(myArray)) works better in this case. – GBMan Apr 24 '20 at 22:33
8

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);

Source: link

Margus
  • 18,332
  • 12
  • 51
  • 101
  • 1
    The *primitive types* comment applies to the `for` loop in the question as well. – user113716 Oct 20 '10 at 13:56
  • 4
    if I were copying an array of objects, I would expect the new array to reference the same objects rather than cloning the objects. – lincolnk Oct 20 '10 at 14:14
8

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marian07
  • 1,414
  • 3
  • 23
  • 38
7

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.

serv-inc
  • 29,557
  • 9
  • 128
  • 146
6

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ciembor
  • 6,732
  • 11
  • 51
  • 92
6

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();
  });
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
martinedwards
  • 4,800
  • 1
  • 29
  • 30
  • 3
    In Javascript there aren't two-dimensional arrays. There are just arrays containing arrays. What you are trying to do is a *deep copy* which is not required in the question. – Aloso Jan 04 '17 at 21:19
6

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:

Enter image description here

Results:

Enter image description here

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
kyndigs
  • 3,040
  • 1
  • 15
  • 21
  • 1
    `arguments` is not a proper array and he's using `call` to force `slice` to run on the collection. results may be misleading. – lincolnk Oct 20 '10 at 14:17
  • Yeh I meant to mention that in my post that these stats would probably change now with the broswers improving, but it gives a general idea. – kyndigs Oct 20 '10 at 14:41
  • 2
    @diugalde I think the only situation where posting code as a picture is acceptable is when the code is potentially dangerous and should not be copy-pasted. In this case though, it's quite ridiculous. – Florian Wendelborn Jun 03 '16 at 00:49
5

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Gor
  • 2,430
  • 5
  • 19
  • 39
5

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)

Zibri
  • 7,056
  • 2
  • 42
  • 38
4

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']
balfonso
  • 581
  • 1
  • 7
  • 16
4

Fastest way to clone an Array of Objects will be using spread operator

var clonedArray=[...originalArray]

but the objects inside that cloned array will still pointing at the old memory location. hence change to clonedArray objects will also change the orignalArray.

var clonedArray = originalArray.map(({...ele}) => {return ele})

this will not only create new array but also the objects will be cloned to.

3

A simple solution:

original = [1,2,3]
cloned = original.map(x=>x)
Caio Santos
  • 1,164
  • 8
  • 9
3
        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);
Anki
  • 55
  • 1
  • 11
  • It's a valid thing to point out about how changing `cloneNums[0][0]` in your example propagated the change to `nums[0][0]` - but that's because the `nums[0][0]` is effectively an object whose reference is copied into `cloneNums` by the spread operator. All that is to say, this behaviour won't affect code where we are copying by value (int, string etc literals). – Aditya M P Jul 18 '19 at 08:45
1

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))

DevLoverUmar
  • 4,509
  • 4
  • 27
  • 41
1

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)
Shuvro
  • 131
  • 1
  • 6
1

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.

nologin
  • 1,199
  • 6
  • 15