How to deep clone an object in JavaScript?

Vajid KagdiVajid Kagdi
2 min read

Native deep cloning

There's now a JS standard called "structured cloning", that works experimentally in Node 11 and later, will land in browsers, and which has polyfills for existing systems.

The structuredClone global function is provided by Node 17.0:

const clone = structuredClone(value)

The HTML standard includes an internal structured cloning/serialization algorithm that can create deep clones of objects. It is still limited to certain built-in types, but in addition to the few types supported by JSON it also supports Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays, and probably more in the future. It also preserves references within the cloned data, allowing it to support cyclical and recursive structures that would cause errors for JSON.

Previous versions: The v8 module in Node.js (as of Node 11) exposes the structured serialization API directly, but this functionality is still marked as "experimental", and subject to change or removal in future versions. If you're using a compatible version, cloning an object is as simple as:

const v8 = require('v8');

const structuredClone = obj => {
  return v8.deserialize(v8.serialize(obj));
};

Fast cloning with data loss - JSON.parse/stringify

If you do not use Dates, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays or other complex types within your object, a very simple one liner to deep clone an object is:

const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
  re: /.*/,  // lost
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString()

Cloning using a library

Since cloning objects is not trivial (complex types, circular references, function etc.), most major libraries provide function to clone objects. Don't reinvent the wheel - if you're already using a library, check if it has an object cloning function. For example,

  • lodash - cloneDeep; can be imported separately via the lodash.clonedeep module and is probably your best choice if you're not already using a library that provides a deep cloning function
  • AngularJS - angular.copy
  • jQuery - jQuery.extend(true, { }, oldObject); .clone() only clones DOM elements
  • just library - just-clone Part of a library of zero-dependency npm modules that do just do one thing. Guilt-free utilities for every occasion.
0
Subscribe to my newsletter

Read articles from Vajid Kagdi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vajid Kagdi
Vajid Kagdi

Graduated with a Master’s degree in Software Engineering from San Jose State University in December 2019 and currently working at PayPal on the Customer Journey Platform. I enjoy generating new ideas and devising feasible solutions to broadly relevant problems. My colleagues would describe me as a driven, resourceful individual who maintains a positive, proactive attitude when faced with adversity. Interested to work in areas related to Distributed Systems, Cloud Infrastructure and Micro-Services. I get a lot of satisfaction from the constant learning and puzzle solving that comes with my profession and contributing to a successful and worthwhile product. My expertise includes project design and management, data analysis and interpretation, and the development and implementation of software products.