How to copy/clone objects in javascript
Tags: javascript
Published: 2021-02-03 10:39:31

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

A very common task is to copy an object. There are plenty of ways to copy objects in Javascript, they vary in execution speed and limitations regarding data types.

The pitfall here is copying by reference instead of by value, or better creating a shallow instead of a deep copy. Why? Well, let me explain a bit. 🤓

### [<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-vs-shallow-copy)Deep Copy vs. Shallow Copy

- **Deep Copy:** Copying by value would result in two unrelated objects with same value.
- **Shallow Copy:** Copying by reference means that you have two objects that point to the same data in memory.

If you make a shallow copy of object A to object B, and you change any value in the object B it will also manipulate the object A, since it points to the same reference. If the copied data is a primitive it will copy the value.

A **shallow copy** successfully copies primitive data types, but any object will not be recursively copied, instead the reference will copied.

A **deep copy** creates a copy of primitive (Boolean, String, Number, BigInt, Symbol) and structural data types (Abjects, Array, Map, Set, Weakmap,...). MDN docs provide a great reference for [data types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures).

[💰: Start your cloud journey with $100 in free credits with DigitalOcean!](https://m.do.co/c/29f238135b61)

## [<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-objects)Shallow Copy Objects

When copying/cloning objects the data type of the properties is key to decide what method can be used.

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

- \_.clone (lodash)
- Object.assign()
- ... (spread)

### [<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. The performance is good and if you use the third-party library lodash already in your application it is a viable option.

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

const beer = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
};

const clonedBeer = _.clone(beer);
```

### [<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>](#objectassign)Object.assign()

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the target object. `Object.assign` performs a **shallow copy** of an object.

Syntax: `Object.assign(target, ...sources)`, see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

```
const beer = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
};

const clonedBeer = Object.assign({}, beer);
```

### [<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 beer = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
};

const clonedBeer = { ...beer };
```

## [<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-objects)Deep Copy Objects

All methods above create shallow copies of objects. If you have non primitive data types as properties, and you try to make a copy, the object will be copied, **BUT** the underlying objects will be passed by reference to the new object. This means a shallow copy instead of a deep copy has been created.

There are several methods to create a deep clone.

- jQuery.extend()
- JSON - not recommended!
- \_.clonedeep()

### [<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 obj = {
  name: 'mario',
  food: 'pizza',
};
const objCopy = jQuery.extend(true, [], obj);
```

### [<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-not-recommended)JSON methods (not recommended)

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.

**IMPORTANT:** This method can't be used for copying EVERY object. If the object property (JavaScript) does not have a JSON equivalent, it will be lost in the process of serializing - deserializing.

```
// This will work
const beerA = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
};

const clonedBeerA = JSON.parse(JSON.stringify(beerA));

// This won't work. The function drinkBeer will not be copied and new Date() will be copied as a string.
const beerB = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
  date: new Date(),
  drinkBeer: function() {
    this.amount -= 1;
  },
};

const clonedBeerB = JSON.parse(JSON.stringify(beerB));
```

### [<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 object.

```
// import lodash cloneDeep
const cloneDeep = require('lodash.cloneDeep');

const beer = {
  id: 12345,
  name: 'beer',
  icon: '🍺',
  amount: 10,
  date: new Date(),
  drinkBeer: function() {
    this.amount -= 1;
  },
};

const clonedBeer = cloneDeep(beer);
```

There are several methods to create a deep clone of an object. I recommend to use Lodash, it's convenient and fast.

#### [<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>](#pro-tip)Pro Tip

Import a single function from Lodash to reduce the size of your dependencies.

```
const clone = require('lodash.clone');
const clonedeep = require('lodash.clonedeep');
```

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/), [Flavio](https://flaviocopes.com/how-to-clone-javascript-object/)

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