deepClone
Deep clones an object using JSON serialization. Note: Does not preserve functions, symbols, undefined, Date, Map, Set, etc.
1/**
2 * Deep clones an object using JSON serialization.
3 * Note: Does not preserve functions, symbols, undefined, Date, Map, Set, etc.
4 *
5 * @param obj - The input object to clone.
6 * @returns A deep copy of the input object.
7 */
8export function deepClone<T>(obj: T): T {
9 return JSON.parse(JSON.stringify(obj));
10}
Simple and Readable
Uses a well-known
JSON.stringify
+JSON.parse
pattern, making the intent clear and understandable at a glance.Performs a Deep Copy
Recursively copies nested objects and arrays, avoiding references to the original structure.
Fast for JSON-Compatible Data
Highly performant for plain data structures that don't include special types like functions or Dates.
Stateless and Pure
Produces a clean, immutable clone without side effects or shared references.
Tests | Examples
1test('deepClone - clones nested objects correctly', () => {
2 const original = { a: 1, b: { c: 2 } };
3 const clone = deepClone(original);
4
5 expect(clone).toEqual(original);
6 expect(clone).not.toBe(original);
7 expect(clone.b).not.toBe(original.b);
8});
9
10test('deepClone - clones arrays correctly', () => {
11 const original = [1, [2, 3], { a: 4 }];
12 const clone = deepClone(original);
13
14 expect(clone).toEqual(original);
15 expect(clone).not.toBe(original);
16 expect(clone[1]).not.toBe(original[1]);
17 expect(clone[2]).not.toBe(original[2]);
18});
19
20test('deepClone - ignores non-serializable properties', () => {
21 const original = {
22 a: 1,
23 b: undefined,
24 c: () => 42,
25 d: Symbol('x'),
26 e: new Date(),
27 };
28 const clone = deepClone(original);
29
30 expect(clone).toEqual({ a: 1 }); // only a survives
31});
32
33test('deepClone - works with null and primitives', () => {
34 expect(deepClone(null)).toBeNull();
35 expect(deepClone(42)).toBe(42);
36 expect(deepClone('test')).toBe('test');
37 expect(deepClone(true)).toBe(true);
38});
Common Use Cases
Immutability in State Management
Create independent deep copies of state objects in libraries like Redux or MobX.
Resetting Data
Clone initial values to reset forms, configs, or game state without affecting originals.
Serialization-Safe Data Transfer
Clone and prepare plain objects for sending via APIs, localStorage, or message passing.
Testing and Mocking
Clone test data to ensure modifications in one test don’t affect others.
Snapshotting and Undo History
Store full copies of objects at various points in time to support undo/redo or diffing.