<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = { base };
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = JSON.parse(JSON.stringify(base));
function myClone(aObject) {
// Prevent undefined objects
// if (!aObject) return aObject;
let bObject = Array.isArray(aObject) ? [] : {};
let value;
for (const key in aObject) {
// Prevent self-references to parent object
// if (Object.is(aObject[key], aObject)) continue;
value = aObject[key];
bObject[key] = (typeof value === "object") ? myClone(value) : value;
}
return bObject;
};
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = myClone(base);
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = _.cloneDeep(base);
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = jQuery.extend(true, {}, base);
const base = {
firstName: 'John',
lastName: 'Doe',
size: 170,
birthDate: new Date(1985, 0,15),
married: true,
address: {
street: '2 av Victor Hugo',
country: 'FR',
},
childrens: [
{
name: 'Paul',
age: 8,
},
],
functions: [],
otherObjs: {
mySet: new Set(["a","b","c"]),
myMap: new Map([["apples", 500],["bananas", 300],["oranges", 200]]),
myErr: new Error("Oups !"),
myReg: new RegExp(/ab+c/, "i"),
myBlob: new Blob(["<html>…</html>"], {type: 'text/html'}),
myFile: new File([""], "filename"),
myArrBuff: new ArrayBuffer(8),
myImgData: new ImageData(300, 300),
},
}
const copy = structuredClone(base);
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Spread operator (...) | |
JSON.parse(JSON.stringify()) | |
Custom function | |
Lodash.cloneDeep() | |
jQuery.extend(true) | |
structuredClone() |
Test name | Executions per second |
---|---|
Spread operator (...) | 19177.8 Ops/sec |
JSON.parse(JSON.stringify()) | 13989.3 Ops/sec |
Custom function | 5.9 Ops/sec |
Lodash.cloneDeep() | 9801.1 Ops/sec |
jQuery.extend(true) | 18136.2 Ops/sec |
structuredClone() | 1928.4 Ops/sec |
It looks like you're presenting benchmark results for different JavaScript operations.
To summarize, the results show that:
Overall, it seems that the spread operator is currently the fastest way to create a deep copy in JavaScript!