Quick deep cloning for JavaScript.
Unsafe for use on cyclical data structures. Does not copy functions as object properties.
Pass an object to clone as the first argument.
Pass true as the second argument to construct prototypes, empty or false to instantiate as plain objects.
Performance comes at a cost:
- no cyclic objects
- no protos that require arguments on construction (if
castflag istrue) - no objects that shadow global proto properties
- no polluted base prototypes
clone(obj,cast=false)constqdclone=require('quick-deep-clone');letx={str: 'str',num: 10,arr: [0,1,2]};functionA(){this.str='str';this.num=10;this.arr=[0,1,2];}// deep clone a plain objectconsole.log(qdclone(x));// deep clone a prototyped objectconsole.log(qdclone(newA(),true));// deep clone a prototyped object as a plain objectconsole.log(qdclone(newA(),false));| Package | Time (ms) |
|---|---|
| deep-clone@3.0.3 | 1361 |
| rfdc@1.1.4 | 1048 |
| qdclone | 441 |
| qdclone (* with casting) | 525 |
* only quick-deep-clone supports casting prototypes
const{ performance }=require('perf_hooks');constcloners={'deep-clone': require('deep-clone'),'rfdc': require('rfdc')(),'qdclone': require('quick-deep-clone')};constITERATIONS=10000;setImmediate(()=>{letx=makeX();console.log('\nRunning...\n')runBench('deep-clone',x,ITERATIONS);runBench('rfdc',x,ITERATIONS);runBench('qdclone',x,ITERATIONS);console.log('Running with prototype casting (only supported by qdclone)...\n');runBench('qdclone',x,ITERATIONS,true);});functionrunBench(type,obj,iterations, ...args){letcloned;console.log(`Clone via ${type}...`);letbenchStart=performance.now();for(leti=0;i<iterations;++i){cloned=cloners[type](obj, ...args);}console.log(`${performance.now()-benchStart} ms\n`);returncloned;}functionmakeX(){letx={str: 'str',num: 10,arr: [0,1,2],date: newDate(),bool: false,sub: {str2: 'abcdefghijklmnopqrstuvwxyz',num2: 9999999.9999999,bool2: true,arr2: [-.0000001,true,'asdf',100000.00001,[1,2,3],'loooooooooooong']}};letx2={x: JSON.parse(JSON.stringify(x))};letx3={x: JSON.parse(JSON.stringify(x)),x2: JSON.parse(JSON.stringify(x2))};letxs=[];for(leti=0;i<100;++i){xs.push(JSON.parse(JSON.stringify(x)));}returnnewclassX{constructor(){this.x=x;this.x2=x2;this.x3=x3;this.xs=xs;}}}Feel free to make changes and submit pull requests whenever.
Mousetouch uses the MIT license.