-
-
Save raphaelchaib/43df59d257d7d6dd44b7cff5b504cb59 to your computer and use it in GitHub Desktop.
Javascript Cloning
This file contains 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
// FROM http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object | |
// When I had to implement general deep copying I ended up compromising by | |
// assuming that I would only need to copy a plain Object, Array, Date, String, | |
// Number, or Boolean. The last 3 types are immutable, so I could perform a | |
// shallow copy and not worry about it changing. I further assumed that any | |
// elements contained in Object or Array would also be one of the 6 simple | |
// types in that list. This can be accomplished with code like the following: | |
function clone(obj) { | |
// Handle the 3 simple types, and null or undefined | |
if (null == obj || "object" != typeof obj) return obj; | |
// Handle Date | |
if (obj instanceof Date) { | |
var copy = new Date(); | |
copy.setTime(obj.getTime()); | |
return copy; | |
} | |
// Handle Array | |
if (obj instanceof Array) { | |
var copy = []; | |
for (var i = 0, len = obj.length; i < len; i++) { | |
copy[i] = clone(obj[i]); | |
} | |
return copy; | |
} | |
// Handle Object | |
if (obj instanceof Object) { | |
var copy = {}; | |
for (var attr in obj) { | |
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); | |
} | |
return copy; | |
} | |
throw new Error("Unable to copy obj! Its type isn't supported."); | |
} | |
// The above function will work adequately for the 6 simple types I mentioned, | |
// as long as the data in the objects and arrays form a tree structure. That | |
// is, there isn't more than one reference to the same data in the object. For | |
// example: | |
// This would be cloneable: | |
var tree = { | |
"left" : { "left" : null, "right" : null, "data" : 3 }, | |
"right" : null, | |
"data" : 8 | |
}; | |
// This would kind-of work, but you would get 2 copies of the | |
// inner node instead of 2 references to the same copy | |
var directedAcylicGraph = { | |
"left" : { "left" : null, "right" : null, "data" : 3 }, | |
"data" : 8 | |
}; | |
directedAcyclicGraph["right"] = directedAcyclicGraph["left"]; | |
// Cloning this would cause a stack overflow due to infinite recursion: | |
var cylicGraph = { | |
"left" : { "left" : null, "right" : null, "data" : 3 }, | |
"data" : 8 | |
}; | |
cylicGraph["right"] = cylicGraph; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment