Native deep cloning
It’s known as “structured Cloning”, works experimentally at Node 11 and later and will hopefully be available in browsers. This answer has more details.
Fast cloning with data loss – JSON.parse/stringify
If you don’t use Date
s, or functions, Infinity
, RegExps Maps, Sets Blobs File Lists ImageDatas, Maps. A very simple way to deep clone an object using just one liner 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()
For benchmarks, see Corban’s answer
Reliable cloning using a library
Cloning objects is not an easy task due to complex types, circular references, and function. Most libraries that are significant provide a function to copy objects.Do not reinvent the wheelIf you are already using a library check to see if it contains an object cloning function. You can use this example:
Dash – cloneDeep
;can be imported separately using the dash. If you don’t have a library with deep cloning capabilities, clone deep module is your best option.
AngularJS – angular.copy
jQuery.extend(true, { }, oldObject)
;only .clone()
elements of DOM.
ES6 (shallow copy)
Note that ES6 has two shallow copy mechanisms. Spread syntax () and Object.assign()
, which copy all of their enumerable property values from one object to the next. Take, for example:
var A1 = {a: "2"};
var A2 = Object.assign({}, A1);
var A3 = {...A1}; // Spread Syntax
Check out this benchmark: http://jsben.ch/#/bWfk9
In my tests that were based on speed, I was successful.
JSON.parse(JSON.stringify(obj))
This is the slowest and most difficult way to deep-clone an object (it’s slower than jQuery.extend, with deep
flag set true to 10-20%).
jQuery.extend performs well when the deep
flag to false
is used (shallow Clone). This is a good option as it includes extra logic for type verification and doesn’t duplicate over undefined properties etc. But, it can also slow you down.
If you understand the structure of your objects or are able to avoid deep-nested arrays, then you can write simple for (var i in obj)
loops to clone your object while checking if it property.
Final note: If you are trying to clone a well-known object structure in a hot circuit, you can achieve MUCH MUCH more performance by simply in-lining the Cloning procedure and manually building the object.
JavaScript trace engines can be slow at optimizing for..in
Loops. Checking property could also slow you down.
var clonedObject = { knownProp: obj.knownProp, .. }
Beware using theJSON.parse(JSON.stringify(obj))
method onDate
objects -JSON.stringify(new Date())
returns a string representation of the date in ISO format, whichJSON.parse()
You don'tConvert back into aDate
objects. For more details, refer to this answer.
Notably, native cloning may not be the best option in Chrome 65. JSPerf suggests that you can perform native cloning to create a new functionality.800xJSON.stringify is more slow than JSON.stringify. Stringify is lightning fast across all of the boards.
Update for ES6
Javascript ES6? Try this native method of cloning and shallow copy.
Object.assign({}, obj);
You can only use variables and not functions if your object has no other objects
var newObject = JSON.parse(JSON.stringify(oldObject));
Leave a Reply