Last active
January 27, 2018 07:36
-
-
Save amitmbee/8e6f784fb5cd57589ff2e97e1bd1cb08 to your computer and use it in GitHub Desktop.
[Javascript Object Deep-Cloning methods] #javascript
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
//JSON.parse | |
const obj = /* ... */; | |
const copy = JSON.parse(JSON.stringify(obj)); | |
/*The downside here is that you create a temporary, potentially big string just to pipe it back into a parser. Another downside is that this approach cannot deal with cyclic objects. And despite what you might think, those can happen quite easily. For example when you are building tree-like data structures where a node references its parent, and the parent in turn references its own children.*/ | |
const x = {}; | |
const y = {x}; | |
x.y = y; // Cycle: x.y.x.y.x.y.x.y.x... | |
const copy = JSON.parse(JSON.stringify(x)); // throws! | |
//Additionally, things like Maps, Sets, RegExps, Dates, ArrayBuffers and other built-in types just get lost at serialization. | |
//MessageChannel | |
//As I said, whenever you call postMessage the structured clone algorithm is used. We can create a MessageChannel and send ourselves a message. On the receiving end the message contains a structural clone of our original data object. | |
function structuralClone(obj) { | |
return new Promise(resolve => { | |
const {port1, port2} = new MessageChannel(); | |
port2.onmessage = ev => resolve(ev.data); | |
port1.postMessage(obj); | |
}); | |
} | |
const obj = /* ... */; | |
const clone = await structuralClone(obj); | |
//The downside of this approach is that it is asynchronous. That is not a big deal, but sometimes you need a synchronous way of deep-copying an object. | |
//Notification API | |
//After tweet-storming about this whole journey on Twitter, Jeremy Banks showed me that there’s a 3rd way to tap into structural cloning: The Notification API. Notifications have a data object associated with them that gets cloned. | |
function structuralClone(obj) { | |
return new Notification('', {data: obj, silent: true}).data; | |
} | |
const obj = /* ... */; | |
const clone = structuralClone(obj); | |
//Short, concise. I liked it! However, it basically kicks of the permission machinery within the browser, so I suspected it to be quite slow. Safari, for some reason, always returns undefined for the data object. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment