1. Introduction
In every programming language sometimes there is a need to make an exact copy of one object. Copy that will be a faithful reflection of the base object, with all attributes and fields at every nesting level. In JavaScript we have several ways to make a deep clone of an object.
// our base object
var obj = {
a: "hello",
c: "test",
po: 33,
arr: [1, 2, 3, 4],
anotherObj: {
a: 33,
str: "whazzup"
}
};
2. Using JSON stringify function
var obj2 = JSON.parse(JSON.stringify(obj));
Note that this method will not work if your object contains: Dates, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays or other complex types.
3. Using lodash deep clone method
var obj2 = _.cloneDeep(obj, true);
4. Angular framework comes with angular.copy function
var obj2 = angular.copy(obj);
5. Using jQuery extend function
var obj2 = $.extend(true, {}, obj);
6. Using Object.assign (this makes a shallow copy, thanks Concerned Citizen for pointing this out in comments)
var obj2 = Object.assign({}, obj);
7. Performance comparision
Now lets check the performance comparision.
If you want to check this benchmark by yourself, click this link: http://jsben.ch/P8MHg
8. Conclusion
According to the benchmark test, the fastest way to deep clone an object in javascript is to use lodash deep clone function since Object.assign supports only shallow copy. Unfortunately, this is an external library, if you don't want to use one you can check below deepClone function written in vanilla JS.
function clone(item) {
if (!item) { return item; } // null, undefined values check
var types = [ Number, String, Boolean ],
result;
// normalizing primitives if someone did new String('aaa'), or new Number('444');
types.forEach(function(type) {
if (item instanceof type) {
result = type( item );
}
});
if (typeof result == "undefined") {
if (Object.prototype.toString.call( item ) === "[object Array]") {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
} else if (typeof item == "object") {
// testing that this is DOM
if (item.nodeType && typeof item.cloneNode == "function") {
result = item.cloneNode( true );
} else if (!item.prototype) { // check that this is a literal
if (item instanceof Date) {
result = new Date(item);
} else {
// it is an object literal
result = {};
for (var i in item) {
result[i] = clone( item[i] );
}
}
} else {
// depending what you would like here,
// just keep the reference, or create new object
if (false && item.constructor) {
// would not advice to do that, reason? Read below
result = new item.constructor();
} else {
result = item;
}
}
} else {
result = item;
}
}
return result;
}
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}