Object and Array Deep Clone: How to Implement in JavaScript
A straightforward implementation for a deep clone method in JavaScript

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: