Skip to content

Instantly share code, notes, and snippets.

@tmarshall
Created June 14, 2012 00:16
Show Gist options
  • Save tmarshall/2927289 to your computer and use it in GitHub Desktop.
Save tmarshall/2927289 to your computer and use it in GitHub Desktop.
(Node) JS object clone
/*
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;
}
@tmarshall
Copy link
Author

Any tips on improvements would be appreciated.

@tmarshall
Copy link
Author

Just realized current is not used.

@tmarshall
Copy link
Author

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