patternjavascriptCritical
What is the most efficient way to deep clone an object in JavaScript?
Viewed 0 times
efficientobjectdeepclonethewaywhatmostjavascript
Problem
What is the most efficient way to clone a JavaScript object? I've seen
I've done things like
I've also seen recursive copying functions with various flaws.
I'm surprised no canonical solution exists.
obj = eval(uneval(o)); being used, but that's non-standard and only supported by Firefox.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.
Solution
Native deep cloning
There's now a
If needed, loading the polyfill first:
See this answer for more details, but note these limitations:
Older answers
Fast cloning with data loss - JSON.parse/stringify
If you do not use
See Corban's answer 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,
Guilt-free utilities for every occasion.
There's now a
structuredClone(value) function supported in all major browsers and node >= 17. It has polyfills for older systems.structuredClone(value)If needed, loading the polyfill first:
import structuredClone from '@ungap/structured-clone';See this answer for more details, but note these limitations:
- Function objects cannot be duplicated by the structured clone algorithm; attempting to throws a DataCloneError exception.
- Cloning DOM nodes likewise throws a DataCloneError exception.
- Certain object properties are not preserved:
- The lastIndex property of RegExp objects is not preserved.
- Property descriptors, setters, getters, and similar metadata-like features are not duplicated. For example, if an object is marked readonly with a property descriptor, it will be read/write in the duplicate, since that's the default.
- The prototype chain is not walked or duplicated.
Older answers
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: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 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
- Ramda -
clone
- 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.
Code Snippets
structuredClone(value)import structuredClone from '@ungap/structured-clone';Context
Stack Overflow Q#122102, score: 6002
Revisions (0)
No revisions yet.