DevFiddleDevFiddle
HomeToolsSnippetsArticles
Explore tools
Home>Snippets>Deep Clone Objects in Modern JavaScript
JavaScript
#Objects#Data Structures#ES2022

Deep Clone Objects in Modern JavaScript

Deeply copy nested JavaScript objects and arrays using native structuredClone and fallback recursion.

October 10, 20262 min read

When copying nested objects in JavaScript, shallow copies like Object.assign() or the spread operator ({ ...obj }) only copy top-level properties by value, leaving inner objects referenced by pointer.

The Modern Solution: structuredClone

Modern JavaScript environments (Node.js 17+ and all modern browsers) include a native global method: structuredClone().

const original = {
  name: "DevFiddle",
  tags: ["tools", "snippets"],
  metadata: {
    created: new Date(),
    id: 101
  }
};
 
// Native deep clone in modern JS:
const clone = structuredClone(original);
 
clone.metadata.id = 999;
console.log(original.metadata.id); // 101 (completely independent!)

Recursive Fallback for Older Environments

If your environment or build pipeline targets older runtimes, use this robust recursive cloner that supports nested arrays, plain objects, and dates:

function deepClone(value, hash = new WeakMap()) {
  // Primitives and functions pass by value or reference
  if (Object(value) !== value || typeof value === "function") {
    return value;
  }
 
  // Handle circular references
  if (hash.has(value)) {
    return hash.get(value);
  }
 
  // Handle Dates & RegExp
  if (value instanceof Date) return new Date(value);
  if (value instanceof RegExp) return new RegExp(value.source, value.flags);
 
  // Handle Arrays & Objects
  const result = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));
  hash.set(value, result);
 
  for (const key of Reflect.ownKeys(value)) {
    result[key] = deepClone(value[key], hash);
  }
 
  return result;
}

Why Avoid JSON.parse(JSON.stringify(obj))?

While JSON.parse(JSON.stringify(obj)) is a common shortcut, it has major limitations:

  • Converts Date objects into ISO strings.
  • Discards undefined, Symbol, and function properties.
  • Converts NaN and Infinity into null.
  • Throws an error on circular object references.

Related snippets

Explore more utility functions, patterns, and code snippets.

View all snippets
TypeScript
Debounce Function with TypeScript

A type-safe debounce implementation that delays executing a function until a specified wait time has elapsed.

#TypeScript#Utilities#Performance
View snippet
JavaScript
Fetch with AbortSignal Timeout

Cancel hanging HTTP requests gracefully using AbortSignal.timeout and custom fallback controllers.

#JavaScript#Fetch#Async
View snippet
React
useLocalStorage Custom React Hook

A robust React hook for syncing component state with window.localStorage across tabs.

#React#Hooks#LocalStorage
View snippet
About© DevFiddle 2026