{...obj} and [...arr] give you shallow copies — nested objects are still shared references. Deep cloning makes a completely independent copy. Deep comparison checks if two values are structurally identical. This article implements both, handling all the tricky edge cases.
Prerequisites: Recursion Patterns
1. The Problem with Shallow Copying
Loading editor...
structuredClone() is the modern native solution (Node 17+, browsers 2022+), but implementing it manually teaches you every edge case.
2. Deep Clone — Handling Primitives, Arrays, Objects
Loading editor...
3. Deep Equality — deepEquals(a, b)
Structural equality checks if two values have the same "shape" and values — recursively. Unlike ===, it handles objects, arrays, and edge cases like NaN and +0/-0:
Loading editor...
4. Object.is() — The Built-in Strict Comparison
Object.is() is like === with two fixes:
Loading editor...
5. structuredClone() — The Modern Native Solution
If you're targeting modern browsers, structuredClone handles most cases:
Loading editor...
Key Takeaways
- Shallow copy (
...,Object.assign) only copies top-level properties — nested objects are shared. - Deep clone recursively copies every level — use
seenMap to handle circular references. - Handle special types:
Date(viagetTime()),RegExp(viasource/flags),Map,Set. structuredClone()is the best option for modern targets — but can't clone functions or DOM nodes.- Deep equality needs
NaN===NaNand+0≠-0handling, plus circular ref detection. - Always use a
seenMap for circular reference handling in both clone and equals.
Next: Data #2 — Flatten & Unflatten Objects — convert nested objects to flat key paths and back.
