Created
June 14, 2012 00:16
-
-
Save tmarshall/2927289 to your computer and use it in GitHub Desktop.
(Node) JS object clone
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Clones an argument, intelligently. | |
@param {Object} obj The object being cloned | |
@returns {Object} The cloned object | |
*/ | |
function objectClone(arg /*, originalObjs, newObjs */) { | |
var | |
originalObjs = arguments.length > 1 ? arguments[1] : [ ], // collection of original object values (used to detect where two attributes should equal the same thing) | |
newObjs = arguments.length > 2 ? arguments[2] : [ ], // collection of new objects (to match up to the originals) | |
result, cache, key, type; | |
if ((type = typeof arg) === 'object' || arg instanceof RegExp) { | |
type = Object.prototype.toString.call(arg); | |
// if we found a pointer to an existing object we already passed over (or the original) | |
if (type === '[object Object]' && (cache = originalObjs.indexOf(arg)) > -1) { | |
return newObjs[cache]; | |
} | |
// now the set up the result objects | |
// this is done to override the objects being pointed to | |
switch (type) { | |
case '[object Object]': | |
result = {}; | |
break; | |
case '[object Array]': | |
result = []; | |
break; | |
case '[object Date]': | |
result = new Date(arg.getTime()); | |
break; | |
case '[object Error]': | |
result = new global[arg.name && global[arg.name] ? arg.name : 'Error']; | |
break; | |
case '[object RegExp]': | |
cache = /\/(.*)\/(\w*)/.exec(arg.toString()); | |
result = new RegExp(cache[1], cache[2]); | |
break; | |
default: | |
result = arg; | |
} | |
// creating a reference to both the original and new objects, as a sort of lookup | |
switch (type) { | |
case '[object Object]': | |
case '[object Array]': | |
case '[object Date]': | |
case '[object Error]': | |
case '[object RegExp]': | |
newObjs[originalObjs.push(arg) - 1] = result; | |
break; | |
} | |
} | |
else { | |
result = arg; | |
} | |
for (key in arg) { | |
if (arg.hasOwnProperty(key) && !(type === 'string' && arg.propertyIsEnumerable(key))) { | |
result[key] = objectClone(arg[key], originalObjs, newObjs); | |
} | |
} | |
if (arguments.length < 2) { | |
originalObjs = newObjs = undefined; | |
} | |
return result; | |
} |
Just realized current
is not used.
took out current
, added Error
& RegExp
cloning, attempting to force garbage collection of the reference arrays when finished...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Any tips on improvements would be appreciated.