Object and Array Deep Clone: How to Implement in JavaScript

A straightforward implementation for a deep clone method in JavaScript

Object and Array Deep Clone: How to Implement in JavaScript
Picture by Daniel K Cheung

The Problem

Thanks to native methods for arrays and objects, such as Array.prototype.slice and Object.assign, we are able to create new references for our data copying all the properties/elements in a new instance. But the problem comes when our lists contain nested objects/arrays. Since they are stored in memory with a reference, the implementation of .slice and .assign will just copy that associated address:

const arr = [1, 2, { name: 'Marco' }];const obj = { name: 'Marco', skills: ['JavaScript'] };const copyArr = arr.slice();const copyObj = Object.assign({}, obj);
arr === copyArr; // false, OKobj === copyobj; // false, OKarr[2] === copyArr[2]; // true! What???obj.skills === copyObj.skills; // true! What???

So, how can we create a deep copy that always creates new instances of our nested properties?

The Solution

There are tons of solutions available online, and many libraries like Lodash already provide a solution. But I hope you’ll like my solution. First, it might be useful to understand what happens behind the scenes:

function clone(input) {  if (input === null || typeof input !== 'object') return input;
  const output = input.constructor();
  for (const key of Object.keys(input)) {    output[key] = clone(input[key]);  }
  return output;}
const arr = [1, 2, { name: 'Marco' }];const obj = { name: 'Marco', skills: ['JavaScript'] };const copyArr = clone(arr);const copyObj = clone(obj);
arr === copyArr; // false, OKobj === copyObj; // false, OKarr[2] === copyArr[2]; // false, OKobj.skills === copyObj.skills; // false, OK

As you can see, it’s pretty simplistic and easy to read, but it does its job well.

It takes an input of any type and returns a new instance, copying all the properties and invoking recursively the function if a nested object/array is found.

Keep in mind that some types don’t necessarily need to be cloned, such as functions or symbols, so it's safe to copy their reference.

Last updated: