Last active
January 29, 2018 12:29
-
-
Save AKST/0feca694a9b6741311999fa75229bbcd to your computer and use it in GitHub Desktop.
A function for deep copying objects, that makes the assumption that the constructors of these objects are stateless.
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
function deepcopy (value) { | |
// if it's anything other than an object | |
// than let immediately return it. | |
switch (typeof value) { | |
case 'object': break; | |
default: return value; | |
} | |
// If it's a null let also return that. | |
if (value === null) return value; | |
// This is probably more efficient... keyword being 'probably' lol | |
if (Array.isArray(value)) return value.map(deepcopy); | |
// this kind of makes the assumption that the constructors | |
// for these objects are stateless, and initialising an object | |
// this way is safe... | |
const prototype = Object.getPrototypeOf(value); | |
const copy = Object.create(prototype); | |
const descriptors = Object.getOwnPropertyDescriptors(value); | |
Object.keys(descriptors).forEach(key => { | |
const descriptor = descriptors[key]; | |
// anything that is set in the class via `this.blah = blah` | |
// will be deepcopied in this way. As we know | |
if ('value' in descriptor) { | |
const newDesciptor = Object.assign( | |
{}, | |
descriptor, | |
{ value: deepcopy(value[key]) } | |
); | |
Object.defineProperty(copy, key, newDesciptor); | |
} | |
else { | |
Object.defineProperty(copy, key, descriptor); | |
} | |
}); | |
return copy; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If your class or objects doesn't have any stateful closures the function above works fine, but there is one way to break this and that is for an object to use closures, like the following
I think the main take away from this is, you really can't deep copy objects in a non purely functional language (where deep copying is irrelevant anyways). Now if all you're doing is deep copying vanilla javascript objects you're fine, but you should simply the function above, as I'm not to sure how efficient
Object.getPrototypeOf
is 🤔 I imagineObject.clone
is fine, but idk.