See http://jsfiddle.net/ogtfqgmh/13/ <html> <head> <title>cloneObject and cloneObjectAsync/title> <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.js"></script> </head> <body> <div id="log"> </div> </body> </html> [code] and [code] var sa = { m : { /* COPYLEFTED - PERPETUALLY FREE FOR ALL TYPES OF USAGE DISCLAIMER : NO WARRANTIES EXPRESSED OR IMPLIED, USE ONLY AT YOUR OWN RISK (c) and (r) 2014-Nov by Rene Veerman <info@seductiveapps.com> cloneObjectAsync has been tested on large arrays (>2MB in size, <100MB in size) */ settings : { cloneObjectAsync : { commands : [] }, cloneObject : { circulars : [] } }, cloneObject : function (v) { var cIdx = sa.m.settings.cloneObject.circulars.length; sa.m.settings.cloneObject.circulars[cIdx] = []; return sa.m.cloneObject_do(cIdx, v, ''); }, cloneObject_circularFound : function (cIdx, v) { var c = sa.m.settings.cloneObject.circulars[cIdx]; for (var i=0; i<c.length; i++) { if (c[i].v===v) return c[i]; } return false; }, cloneObject_addCircular : function (cIdx, v, path) { var c = sa.m.settings.cloneObject.circulars[cIdx]; c[c.length] = { v : v, path : path }; }, cloneObject_do: function (cIdx, v, path) { var test = {}; for (var x in v) { if (v[x] === window) { test[x] = '-window node skipped-'; } else if (v[x] && v[x].tagName) { test[x] = '-DOM node skipped-'; } else { var cr = sa.m.cloneObject_circularFound(cIdx,v[x]); if (typeof cr==='object') { test[x] = '-Circular reference skipped- ['+cr.path+']'; } else { //sa.m.log (1, path+'/'+x); if ( x=='context' || x=='parentNode' || x=='panel' || x=='styleSheets' || x=='defaultView' ) { test[x] = '[skipped] ['+x+']'; } else if (typeof v[x] == 'object') { if (v[x]!==undefined && v[x]!==null) sa.m.cloneObject_addCircular (cIdx, v[x], path+'/'+x); test[x] = new sa.m.cloneObject_do (cIdx, v[x], path+'/'+x); } else { test[x] = v[x]; } } } } return test; }, cloneObjectAsync : function (cmd) { var rscc = sa.m.settings.cloneObjectAsync.commands; var cmdIdx = rscc.length; rscc[cmdIdx] = cmd; cmd.result = {}; cmd.lastPause = 0; cmd.lastCheck = 0; cmd.countKeys=1; if (!cmd.cIdx) { cmd.cIdx = sa.m.settings.cloneObject.circulars.length; sa.m.settings.cloneObject.circulars[cmd.cIdx] = []; }; var queue = [{parent:null,source:cmd.original,target:cmd.result,path:''}]; var processQueue = function() { if (queue.length==0) { cmd.resultCallback(cmd); } else { var it = queue.shift(); var logStr = 'sa.m.cloneObjectAsync(): now copying '+it.path; //sa.m.log (1, logStr); if (cmd.statusUpdateTo) jQuery('#'+cmd.statusUpdateTo).html(logStr); /* todo: attempt to copy members of Array in the correct order if (it.source instanceof Array) { for (var k=0; k<it.source.length) { it.target[k] = it.source[k]; } } */ //debugger; for (var k in it.source) { if (/*typeof k!=='number' && */it.source.hasOwnProperty(k)) { if (it.source[k] === undefined) { it.target[k] = '[undefined]'; } else if (typeof it.source[k]=='object' && it.source[k]!==null && it.source[k].contentWindow) { it.target[k] = '[iframe node skipped]'; } else if (it.source[k] == window) { it.target[k] = '[window node skipped]'; } else if (it.source[k] && it.source[k].tagName) { it.target[k] = '[DOM node skipped] [id="'+it.source[k].id+'" class="'+it.source[k].className+'" style="'+(it.source[k].style?it.source[k].style.cssText:'')+'"]'; } else if ( k=='context' || k=='parent' || k=='parentNode' || k=='panel' || k=='styleSheets' || k=='defaultView' || k=='original' || k=='traced' || k=='userActions' || k=='_request' || it.path.match(' / sa / settings') || it.path.match(' / sa / json / decode / contexts') || it.path.match(' / sa / jsonViewer / options / thisCmd') || it.path.match(' / sa / jsonViewer / settings') || it.path.match(' / sa / vividControls / settings / fadeCmds') || it.path.match(' / sa / tracer / traced ') || it.path.match(' / sa / tracer / userActions ') ) { it.target[k] = '[Dangerously large node skipped]'; } else { var cr = sa.m.cloneObject_circularFound(cmd.cIdx,it.source[k]); if (typeof cr==='object') { it.target[k] = '[Circular reference skipped] ['+cr.path+']'; } else { cmd.countKeys++; //jQuery('#rslv_status2').html (cmd.countKeys + ' - ' + queue.length); if (typeof it.source[k]=='object' && it.source[k]!==null && it.source[k]!=undefined) { if (it.source[k]!==undefined && it.source[k]!==null) sa.m.cloneObject_addCircular (cmd.cIdx, it.source[k], it.path+' / '+k); it.target[k] = (it.source[k] instanceof Array) ? [] : {}; queue.push({parent:it.source, source:it.source[k], target:it.target[k],path:it.path+' / '+k}); } else { it.target[k] = it.source[k]; }; } } } }; //jQuery('#rslv_status2').html (cmd.countKeys + ' - ' + queue.length); var pauseFactor = cmd.countKeys; if (pauseFactor > cmd.lastPause+200) { setTimeout (function () { cmd.lastPause = pauseFactor; cmd.countKeys++; processQueue(); }, 250); } else { processQueue(); }; } }; processQueue(); }, }}; var test = { a : 'b', b : 'c', d : { e : 'f', g : 'h' } }; sa.m.cloneObjectAsync({ original : test, origin : { title : 'test copy'}, statusUpdateTo : 'log', resultCallback : function (cmd) { var testCopied = cmd.result; testCopied.a = 'x'; console.log (test, testCopied); jQuery('#log').html('test.a='+test.a+', testCopied.a='+testCopied.a); } }); Code (markup):
It's an interesting notion, but really if you have an object big enough that cloning it takes long enough to need it async, you've wasted time sending something client side that has no business client-side. Though it could be handy if you were working with node.js server side... actually, is that your intent with these? It really makes no sense to waste so much code on something that to NEED that much code would be too massively oversized to have any business being done with JS in the first place. Especially since the objects one should spend the most time working with are DOM elements, and those already have very fast cloning and walking capabilities.
stop thinking your way of coding is the only good way to code dude. you're making yourself ridiculous.
Stop thinking about wasting megabytes of bandwidth on doing a hundred K or two's job -- ditto, ditto.
Agreed, but right back at you... I know you are but what am I? Really, you'd think you'd learn from your last thread, but I'll leave it to everyone else to belittle your bloated rubbish now; It's very apparent you just want to throw JavaScript at everything for no good reason other than leading yourself down the garden path to failure; have fun with that.