How to copy/clone arrays in javascript
Tags: javascript
Published: 2021-01-24 00:49:00

---
title: How to copy/clone arrays in javascript
published: true
date: 2021-01-10 00:00:00 UTC
tags: javascript
canonical_url: https://www.mariokandut.com/how-to-copy-arrays-in-javascript/
---

There are plenty of ways to copy an array in Javascript, they vary in execution speed and limitations regarding data types.

If you think, _Why just can't I assign the array to the new array?_. Well, let me explain a bit. 🤓

**Arrays are reference values (in javascript).**

This means, when you try to copy it with `const newArray = oldArray`, it will copy the reference to the original array and not copy the values.

```
const beers = ['🍺', '🍺', '🍺'];

const beersCopy = beers;

console.log(beers === beersCopy);
// The console output will be true, because it's pointing to the exact value in memory.
```

This means that arrays in javascript are **MUTABLE**. Please keep that in mind, when working with arrays especially in the context of `Redux` or `MobX`.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#shallow-copy-arrays)Shallow Copy Arrays

When copying or cloning arrays the data type of the value is key to decide what method can be used.

If your array only contains primitive immutables values (numbers, booleans, strings, etc.), you can use the following methods.

- .push
- ... (spread)
- .slice
- Array.from
- \_.clone (lodash)

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#push).push()

A classic array method and the most obvious approach, basically looping over the original array and using the `push()` method to push elements from the original in the new array.

We simply loop over the original array and push each element to the new array.

```
const arr = [1, 2, 3];
const newArr = [];
for (let i = 0; i < arr.length; i++) {
  newArr.push(arr[i]);
}
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#-spread)... (spread)

The spread operator is one of the fastest methods and was introduced with ES6. It's clean and simple and a native method (sorry lodash).

```
const arr = [1, 2, 3];
const newArr = [...arr];
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#slice).slice()

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end `arr.slice([start[, end]])`. The original array will not be modified. This is the fastest way to copy an array.

```
const arr = [1, 2, 3];
const newArr = arr.slice();
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#arrayfrom)Array.from

The `Array.from()` static method creates a new, shallow-copied Array instance from an array-like or iterable object (Map or Set).

It also takes a optional mapping function as the second parameter `Array.from(arrayLike [, mapFn [, thisArg]])`.

```
const arr = [1, 2, 3];
const newArr = Array.from(arr);
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#_clone)\_.clone()

The `_.clone(value)` method from [lodash](https://lodash.com/docs/4.17.15) creates a shallow clone of value. It performs well and if you use lodash already in your application it is a viable option.

```
// import lodash
const _ = require('lodash');

const arr = [1, 2, 3];
const newArr = _.clone(arr);
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#deep-copy-arrays)Deep Copy Arrays

All methods above create shallow copies of arrays. If you have objects as array items, and you try to make a **shallow** copy, the actual array will be copied, **BUT** the underlying objects will be passed by reference to the new array.

Let's have a look at this issue with a code example.

```
const arr = [
  {
    name: 'mario',
    food: 'pizza',
  },
  {
    name: 'luigi',
    food: 'spaghetti',
  },
];

const arrCopy = [...arr];

console.log(arr === arrCopy);
// This will return false, because the array has been copied (shallow copy), new reference in memory.

console.log(arr[0] === arrCopy[0]);
// This will return true, because the reference points to the same place in memory.
```

There are several methods to create a deep clone.

- jQuery.extend()
- \_.clonedeep()
- JSON (stringify/parse)

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#jqueryextend)jQuery.extend()

If you still use jQuery in your project, you can use the [extend](https://api.jquery.com/jquery.extend/) method from jQuery.

```
const arr = [
  {
    name: 'mario',
    food: 'pizza',
  },
  {
    name: 'luigi',
    food: 'spaghetti',
  },
];
const arrCopy = jQuery.extend(true, [], arr);

console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).

console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#_clonedeep)\_.cloneDeep()

The method \_.cloneDeep(value) from Lodash does exactly the same thing as \_.clone(), except that it recursively clones everything in the array.

```
const arr = [
  {
    name: 'mario',
    food: 'pizza',
  },
  {
    name: 'luigi',
    food: 'spaghetti',
  },
];

// import lodash
const _ = require('lodash');

const arrCopy = _.cloneDeep(arr);

console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).

console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#json-methods)JSON methods

JavaScript provides native methods for serialization and deserialization, basically to convert most data types to a JSON string, and then a valid JSON string to an object.

It can be used like this:

```
const arr = [
  {
    name: 'mario',
    food: 'pizza',
  },
  {
    name: 'luigi',
    food: 'spaghetti',
  },
];

const arrCopy = JSON.parse(JSON.stringify(arr));

console.log(arr === arrCopy);
// This will return false, because the array has been copied (new reference in memory).

console.log(arr[0] === arrCopy[0]);
// This will return false, because the reference points to a new one in memory.
```

There are some advantages and disadvantages, when using this approach. An advantage is that it doesn't require a third-party library like Lodash. The disadvantage is that the provided array data needs be serializable and the serializing and deserializing via JSON takes some time, hence this is not the fastest approach.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

References (and Big thanks):[MDN. Resources for developers, by developers.](https://developer.mozilla.org/en-US/), [ScottWRobinson](https://stackabuse.com/clone-arrays-in-javascript/), [Samantha](https://www.samanthaming.com/tidbits/35-es6-way-to-clone-an-array/),

If you want to know more about [Javascript](../tags/javascript), have a look at these [Javascript Tutorials](../tags/javascript).