<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>
<script src="https://cdn.rawgit.com/ivolovikov/fastest-clone/master/index.js"></script>
var source = {a:1,b:1,c:1,d:1,e:1,f:1,g:1,h:{a:-1,b:1,c:1,d:1,e:1,f:1,g:1}};
//var source = {a:1};
//var CloneFactory = FastClone.factory(source);
function clone(value) {
var type = typeof value;
switch (type) {
case 'object':
// null and undefined
if (value == null) {
return value;
}
var result = void 0;
if (value instanceof Date) {
result = new Date();
result.setTime(value.getTime());
return result;
}
else if (value instanceof RegExp) {
result = newRegExp(value);
return result;
}
result = JSON.parse(JSON.stringify(value));
fixTypes(value, result);
return result;
default:
return value;
}
}
function fixPropertyValue(original, copy, key) {
var originalValue = original[key];
var originalType = typeof originalValue;
switch (originalType) {
case 'object':
if (originalValue instanceof Date) {
var newValue = new Date();
newValue.setTime(originalValue.getTime());
copy[key] = newValue;
}
else if (originalValue instanceof RegExp) {
copy[key] = newRegExp(originalValue);
}
else if (originalValue == null) {
copy[key] = originalValue;
}
else {
fixTypes(originalValue, copy[key]);
}
break;
case 'number':
if (isNaN(originalValue)) {
copy[key] = NaN;
}
else if (originalValue == Infinity) {
copy[key] = Infinity;
}
break;
default:
break;
}
}
function fixTypes(original, copy) {
if (original instanceof Array) {
for (var index = 0; index < original.length; index++) {
fixPropertyValue(original, copy, index);
}
}
else {
var keys = Object.getOwnPropertyNames(original);
keys.forEach(function (key) {
fixPropertyValue(original, copy, key);
});
}
}
function newRegExp(value) {
var regexpText = String(value);
var slashIndex = regexpText.lastIndexOf('/');
return new RegExp(regexpText.slice(1, slashIndex), regexpText.slice(slashIndex + 1));
}
var objects = [{ 'a': 1 }, { 'b': 2, c: 3, d: 4 }, {c:3}, 4, 5, 6 ,'hello'];
//var objects = {a:1,b:1,c:1,d:1,e:1,f:1,g:1,h:{a:-1,b:1,c:1,d:1,e:1,f:1,g:1}};
var deep = JSON.parse(JSON.stringify(objects));
var objects = [{ 'a': 1 }, { 'b': 2, c: 3, d: 4 }, {c:3}, 4, 5, 6 ,'hello'];
//var objects = {a:1,b:1,c:1,d:1,e:1,f:1,g:1,h:{a:-1,b:1,c:1,d:1,e:1,f:1,g:1}};
var deep = _.cloneDeep(objects);
//var objects = {a:1,b:1,c:1,d:1,e:1,f:1,g:1,h:{a:-1,b:1,c:1,d:1,e:1,f:1,g:1}};
var objects = [{ 'a': 1 }, { 'b': 2, c: 3, d: 4 }, {c:3}, 4, 5, 6 ,'hello'];
var deep = clone(objects);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
JSON parse | |
_.deepClone | |
fast-clone |
Test name | Executions per second |
---|---|
JSON parse | 315053.4 Ops/sec |
_.deepClone | 282218.6 Ops/sec |
fast-clone | 85869.4 Ops/sec |
Let's dive into the world of JavaScript microbenchmarks.
Benchmark Definition
The benchmark compares three methods for creating a deep clone of an object:
{...obj}
).concat()
method (by joining arrays and objects with dots or brackets).clone()
that handles various types, including dates, regular expressions, and primitive values.Options Compared
The benchmark compares two methods:
{...obj}
): This method creates a shallow copy of the object by spreading its properties into a new object.Pros and Cons
{...obj}
)`:Library Used
The benchmark uses two libraries:
Special JS Feature/Syntax
The benchmark utilizes ES6 features:
{...obj}
) for creating shallow copies of objects.objects.a
) and bracket notation (e.g., objects['a']
) for accessing object properties.Benchmark Results
The latest benchmark results show the following performance characteristics:
In summary, the benchmark highlights the trade-offs between different methods for creating deep clones of objects in JavaScript. The ES6 spread operator offers a simple and efficient solution for shallow copies, while Lodash's _.deepClone provides a more comprehensive cloning function for handling complex data structures.