Question
This question's answers are a[community effort](/help/privileges/edit- community-wiki). Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
What is the most efficient way to clone a JavaScript object? I've seen obj = eval(uneval(o));
being used, but [that's non-standard and only supported by
Firefox](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/uneval).
I've done things like obj = JSON.parse(JSON.stringify(o));
but question the
efficiency.
I've also seen recursive copying functions with various flaws.
I'm surprised no canonical solution exists.
Answer
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.
structuredClone(value)
If needed, loading the polyfill first:
import structuredClone from '@ungap/structured-clone';
See [this answer](https://stackoverflow.com/questions/122102/what-is-the-most- efficient-way-to-deep-clone-an-object-in-javascript/10916838#10916838) for more details.
Older answers
Fast cloning with data loss - JSON.parse/stringify
If you do not use Date
s, 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:
JSON.parse(JSON.stringify(object))
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()
See [Corban's answer](https://stackoverflow.com/questions/122102/what-is-the- most-efficient-way-to-deep-clone-an-object-in-javascript/5344074#5344074) for benchmarks.
Reliable 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.