I'm trying to figure out a way to deep clone a JS class instance while preserving all the prototypes down the chain.
I've seen how to deep clone an object:
JSON.parse(JSON.stringify(instance))
And I have seen how to make a shallow copy of a class instance:
Object.assign( Object.create( Object.getPrototypeOf(instance) ), instance)
But my question is, is there a way to deep clone an instance of a class?
There is no foolproof way to clone all possible types of objects in JS, particularly if it contains references to other objects. A generic cloning argument doesn't know whether an object reference in the clone should contain the same reference (such as a common parent) or whether it needs to clone the object I have a reference too also. It isn't possible to know that generically as it really depends upon the implementation of the object.
If there are circular references to objects such as parent to child and child to parent, it gets even more complicated.
As another example, imagine an object that as part of its constructor, it creates a unique object ID, registers that id with some service and then stores the ID in its instance data. There's no way for a generic clone mechanism to know that logic (generating a new ID and registering it with some service) is required to make a new object. That type of logic would have to be done by code specific to that object that knows what to do.
As another example, a constructor might create closures (with access to private information) that there is no way to duplicate from the outside.
As another example, a constructor might bind methods to its own instance that a generic clone would have no idea it needed to do.
The best way to clone an object is with code built into the implementation of the object that knows how to clone itself such as adding a .clone()
method (or name it whatever you want) on the object itself and have the object support making a duplicate of itself. Then, it can do the right thing with any instance data which only the object implementation itself can know how to handle all possible types of instance data.
I recommend using Lodash's cloneDeep. It works with all types, function and Symbol are copied by reference.
Using the JSON.parse(JSON.stringify(myObject))
way is problematic when there's circular reference. Also, it replaces the object's methods to undefined
and reorders the properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With