Retry with Exponential Backoff
Automatically retry failed operations with increasing delays and jitter to prevent thundering herd problems.
Create a fully independent copy of nested objects where modifying the clone never affects the original.
function deepClone(obj) {
// Handle primitives and null
if (obj === null || typeof obj !== 'object') {
return obj;
}
// Handle Date
if (obj instanceof Date) {
return new Date(obj.getTime());
}
// Handle Array
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item));
}
// Handle Object
const cloned = {};
for (const key of Object.keys(obj)) {
cloned[key] = deepClone(obj[key]);
}
return cloned;
}
Let us trace what happens when you clone a nested config object:
Input: { db: { host: "localhost", ports: [5432, 5433] } }
Step 1: deepClone({ db: { host: "localhost", ports: [5432, 5433] } })
→ obj is Object → create new {}
→ key "db" → recurse
Step 2: deepClone({ host: "localhost", ports: [5432, 5433] })
→ obj is Object → create new {}
→ key "host" → recurse
Step 3: deepClone("localhost")
→ string is primitive → return "localhost" (new copy)
Step 4: deepClone([5432, 5433])
→ obj is Array → map each element
→ deepClone(5432) → primitive → return 5432
→ deepClone(5433) → primitive → return 5433
→ return NEW array [5432, 5433]
Result: completely independent copy — no shared references
The critical difference from Object.assign or the spread operator is that those only create shallow copies. If you modify a nested property on the copy, it modifies the original too because they share the same inner reference. Deep clone walks every level and creates new objects at each depth.
Shallow copy (spread operator):
const copy = { ...original };
copy.db.host = "remote";
console.log(original.db.host); // "remote" — MUTATED the original!
Deep clone:
const copy = deepClone(original);
copy.db.host = "remote";
console.log(original.db.host); // "localhost" — original untouched
// Safe state snapshot before mutation
const previousState = deepClone(appState);
applyUserChanges(appState);
// Undo? Restore from snapshot
if (userClicksUndo) {
appState = previousState;
}
// Safe config per environment
const baseConfig = { db: { host: "localhost", pool: 5 } };
const prodConfig = deepClone(baseConfig);
prodConfig.db.host = "prod-db.internal";
prodConfig.db.pool = 20;
// baseConfig.db.host is still "localhost"
Use this for state snapshots, config duplication, and any case where you need to modify a copy without affecting the original. For simple flat objects, the spread operator is fine. For anything nested, you need a deep clone. Note: structuredClone() is now available natively in modern browsers and Node 17+, but this manual version works everywhere and handles the cases you control.