Last active
March 23, 2023 00:00
-
-
Save fzn0x/e81f26c416fe297d6fd19e28b2fbbad3 to your computer and use it in GitHub Desktop.
Asynchronous Structured Clone (Using The Structured Clone Algorithm) for Deep Copying
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
// postMessage is using the structured clone algorithm | |
function structuredClone(obj) { | |
return new Promise(resolve => { | |
const {port1, port2} = new MessageChannel(); | |
port2.onmessage = ev => resolve(ev.data); | |
obj.y.x = "Now I can modify cyclic objects without "; | |
port1.postMessage(obj); | |
port1.close(); | |
}); | |
} | |
const x = {}; | |
const y = {x}; | |
x.y = y; | |
(async () => { | |
const clone = await structuredClone(x); | |
console.log(clone); | |
})(); |
JSON.parse(JSON.stringify(x));
turns out to be the fastest for deep copying but it does not supports modifying cyclic objects. The alternative is to use MessageChannel postMessage
, it's not as fast as the JSON.parse trick but it returns the correct result as it uses the structured clone algorithm that handles cyclic objects and preserve built-in types well.
There is also history API which is the winner on performance test ( you can re-test anytime ), but it is limited in some browser like Safari or no support at all.
To sum up, refers to these based on the advantages & disadvantages:
- Performance, synchronous, environment limited: History API
- Reliability, cross-browsers solution, asynchronous, slow for large arrays: MessageChannel
postMessage
- Fast but not reliable in cyclic objects and preserve built-in types (Maps, Sets, RegExps, Dates, ArrayBuffers and other built-in types functions won't work after serialization), fastest cross-browsers solution: JSON.parse
This gist inspired by surma.dev is also the one who's re-initiated the native structuredClone
specification, props to him! 😃
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now you can modify cyclic objects without hassle