JavaScript clone object (shallow spread, structuredClone, JSON)

Last reviewed: by
JavaScript clone object (shallow spread, structuredClone, JSON)

javascript clone object and js copy object workflows fall into shallow copies (new top-level object, shared nested references) and deep copies (nested data duplicated). For javascript copy object in modern engines, structuredClone is usually the best native deep clone; JSON.parse(JSON.stringify(x)) is still common but lossy. If you copy plain data from class instances, remember structuredClone does not preserve the original prototype chain.

Tested on: all examples in this tutorial were run with Node.js v20.18.2, and the output shown below each snippet is its exact console output.


Quick reference

Use this table when you need the smallest answer for clone object javascript, copy object js, or object clone javascript tasks: shallow duplicate vs JSON-only deep clone vs structuredClone vs prototype-preserving snapshots.

Goal Approach
Shallow duplicate { ...obj } or Object.assign({}, obj)
Deep clone, JSON-safe plain data JSON.parse(JSON.stringify(obj)) (watch Date, undefined, functions, cycles)
Deep clone, modern default structuredClone(obj) when types fit the algorithm
Prototype + descriptors snapshot Object.create(Object.getPrototypeOf(x), Object.getOwnPropertyDescriptors(x))

Shallow copy with spread — clone object javascript

Spread { ...obj } is the most common clone object javascript pattern: enumerable own properties copy to a new object in one expression. Nested objects stay aliased—mutating a nested field shows up on both sides—while reassigned top-level keys diverge.

javascript
const a = { x: 1, n: { v: 0 } };
const b = { ...a };
b.n.v = 1;
b.x = 2;
console.log(a.n.v, b.n.v, a.x, b.x);
text
1 1 1 2

Nested n is shared (both show 1); top-level x diverges (1 vs 2). Same behavior as other spread operator shallow merges.


Shallow copy with Object.assign

Object.assign({}, src) is another js clone object shallow path: it copies enumerable own properties onto a target object. Nested references behave like spread—k.z updates both views in the output below.

javascript
const o1 = { k: { z: 1 } };
const o2 = Object.assign({}, o1);
o2.k.z = 9;
console.log(o1.k.z, o2.k.z);
text
9 9

for...in manual copy — object clone javascript

A for...in loop is the explicit object clone javascript style when you cannot rely on syntax sugar: copy each key into a fresh object. It is still shallow for nested values, and without Object.hasOwn (or hasOwnProperty checks) you may copy enumerable inherited keys—guard when cloning plain objects that sit on a busy prototype chain.

javascript
const originalObject = { type: "van", tyres: 4 };
const clonedObject = {};
for (const key in originalObject) {
  clonedObject[key] = originalObject[key];
}
console.log(JSON.stringify(clonedObject));
text
{"type":"van","tyres":4}

Object.create + property descriptors — js clone object with prototype

Object.create(Object.getPrototypeOf(src), Object.getOwnPropertyDescriptors(src)) preserves prototype linkage and property descriptors—useful when object clone javascript questions mention getters, setters, or non-enumerable fields. Values are still shallow: the series array below is one shared reference between originalObject and clonedObject unless you deep-clone that branch separately.

javascript
const originalObject = {
  type: "main",
  condition: false,
  series: [13, 17, 19],
  age: 30,
};
const clonedObject = Object.create(
  Object.getPrototypeOf(originalObject),
  Object.getOwnPropertyDescriptors(originalObject)
);
console.log(JSON.stringify(clonedObject));
text
{"type":"main","condition":false,"series":[13,17,19],"age":30}

Deep copy with JSON — lossy

JSON.parse(JSON.stringify(obj)) is a narrow javascript copy object hack: it only survives JSON-safe shapes. undefined keys disappear, Date values stringify, functions and symbols vanish, and circular graphs throw—pair this section with copying arrays when the same JSON caveat applies to collections.

javascript
const j = { a: 1, u: undefined, d: new Date(0) };
const jc = JSON.parse(JSON.stringify(j));
console.log(JSON.stringify(jc));
console.log(typeof jc.d, jc.d);
text
{"a":1,"d":"1970-01-01T00:00:00.000Z"}
string 1970-01-01T00:00:00.000Z

undefined is omitted; Date becomes an ISO string, not a Date instance.


Deep copy with structuredClone — javascript clone

structuredClone is the native javascript clone answer for many plain data graphs: nested objects detach, Date, Map, and other structured-cloneable types round-trip, and circular references can be preserved (MDN: structuredClone). It throws DataCloneError for unsupported types such as functions.

javascript
const o = {
  d: new Date(0),
  n: { v: 1 },
  m: new Map([["k", 1]]),
};
const c = structuredClone(o);
c.n.v = 2;
console.log(o.n.v, c.n.v, c.d instanceof Date, c.m instanceof Map, c.m.get("k"));
text
1 2 true true 1

Nested n is independent (1 vs 2); Date and Map survive cloning.


structuredClone and functions — DataCloneError

Functions are not structured-cloneable: wrapping them in an object and calling structuredClone fails fast with DataCloneError, which is what most js clone object guardrails should catch when user data includes callbacks.

javascript
try {
  structuredClone({ f() {} });
} catch (e) {
  console.log(e.name);
}
text
DataCloneError

Circular references with structuredClone

Unlike JSON stringify, structuredClone can duplicate graphs that point back to themselves—useful when clone object js payloads include parent/child links. The clone keeps the cycle: y.a === y mirrors the original self-reference.

javascript
const x = {};
x.a = x;
const y = structuredClone(x);
console.log(y.a === y);
text
true

Summary

  • Use { ...obj } or Object.assign({}, obj) for shallow javascript clone object copies when nested sharing is acceptable.
  • Use for...in only with clear key filtering (Object.hasOwn) when you need explicit object clone javascript control.
  • Use Object.create + getOwnPropertyDescriptors when prototype and descriptors matter; still plan for nested deep copies.
  • Reserve JSON round-trip for JSON-safe javascript copy object trees; expect Date/undefined/function loss.
  • Prefer structuredClone for modern deep javascript clone work when types fit; catch DataCloneError for unsupported values.

References

MDN pages for structuredClone, spread, Object.assign, Object.create, and JSON—core APIs behind javascript clone object and javascript copy object examples in this guide.


Frequently Asked Questions

1. javascript clone object shallow vs deep?

Shallow copy duplicates top-level keys; nested objects stay the same reference. Deep copy duplicates nested data too so mutations on the clone do not affect the original nested values.

2. Is JSON.parse(JSON.stringify(obj)) a safe javascript copy object for all data?

No. It drops undefined and functions, converts Date to string, loses Map/Set semantics, and throws on circular structures. Use structuredClone when you need a native deep clone for supported types.

3. When should I use structuredClone for js clone object?

Use it for plain data graphs with Date, Map, Set, ArrayBuffer, RegExp, circular refs, etc. It throws DataCloneError for functions and some exotic types, and class instances become plain objects without the original prototype chain.

4. Does Object.assign empty object clone nested objects?

Object.assign({}, src) is shallow like spread. Nested object properties are still shared references unless you deep-clone those branches separately.

5. object clone javascript with lodash?

lodash cloneDeep is a common library choice for deep clones including edge cases; prefer structuredClone in modern runtimes when it fits your data shapes to avoid a dependency.

6. clone object javascript preserving prototype?

Use Object.create(Object.getPrototypeOf(src), Object.getOwnPropertyDescriptors(src)) for own properties and prototype linkage; values are still shallow-copied unless you add a recursive deep strategy.
Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital …

  • JavaScript
  • Web Design