diff --git a/README.md b/README.md index 2e3afc4..1b4867f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1482 TILs and counting..._ +_1483 TILs and counting..._ --- @@ -510,6 +510,7 @@ _1482 TILs and counting..._ - [List Top-Level NPM Dependencies](javascript/list-top-level-npm-dependencies.md) - [Load And Use Env Var In Node Script](javascript/load-and-use-env-var-in-node-script.md) - [Make The Browser Editable With Design Mode](javascript/make-the-browser-editable-with-design-mode.md) +- [Make Truly Deep Clone With Structured Clone](javascript/make-truly-deep-clone-with-structured-clone.md) - [Matching A Computed Property In Function Args](javascript/matching-a-computed-property-in-function-args.md) - [Matching Multiple Values In A Switch Statement](javascript/matching-multiple-values-in-a-switch-statement.md) - [Mock A Function With Return Values Using Jest](javascript/mock-a-function-with-return-values-using-jest.md) diff --git a/javascript/make-truly-deep-clone-with-structured-clone.md b/javascript/make-truly-deep-clone-with-structured-clone.md new file mode 100644 index 0000000..dd898b7 --- /dev/null +++ b/javascript/make-truly-deep-clone-with-structured-clone.md @@ -0,0 +1,61 @@ +# Make Truly Deep Clone With Structured Clone + +There are a lot of ways to make a copy of an object. They are all hacks and +they all fail in certain circumstances. Using the spread trick only gives you a +shallow copy where references to nested objects and arrays can still be +updated. The `JSON.stringify` trick has to make things like dates into strings, +so it is lossy. + +There is however now a dedicated method for deep copies with broad support +called +[`structuredClone`](https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone). +It is available on `window`. Let's take a look at it and see how it comparse to +the spread operator trick. + +```javascript +> // some data setup + +> const data = { one: 1, two: 2, rest: [3,4,5] } + +> const obj = { hello: 'world', taco: 'bell', data } + +> const shallowObj = { ...obj } + +> const deepObj = structuredClone(obj) + +> // let's modify the original `data.rest` array + +> data.rest.push(6) +4 +> data +{ one: 1, two: 2, rest: [ 3, 4, 5, 6 ] } + +> // now let's see who was impacted by that mutation + +> obj +{ + hello: 'world', + taco: 'bell', + data: { one: 1, two: 2, rest: [ 3, 4, 5, 6 ] } +} + +> shallowObj +{ + hello: 'world', + taco: 'bell', + data: { one: 1, two: 2, rest: [ 3, 4, 5, 6 ] } +} + +> deepObj +{ + hello: 'world', + taco: 'bell', + data: { one: 1, two: 2, rest: [ 3, 4, 5 ] } +} +``` + +The `shallowObj` from the spread operator copy was mutated even though we +didn't intend for that. The `deepObj` from `structuredClone` was a true deep +copy and was unaffected. + +[source](https://www.builder.io/blog/structured-clone)