Shallow Copy, Deep Clone, and References in JavaScript

Assigning an object to another variable does not clone it:

1
2
3
4
5
const original = { name: 'Hudson' };
const alias = original;

alias.name = 'Chinh';
console.log(original.name); // "Chinh"

Both variables reference the same object. The variables are separate; the object is not.

Shallow copies

Spread syntax and Object.assign create a new outer object:

1
2
3
4
5
6
7
const original = {
name: 'Hudson',
location: { city: 'Saigon' },
};

const withSpread = { ...original };
const withAssign = Object.assign({}, original);

Both are shallow copies. Nested objects remain shared:

1
2
withSpread.location.city = 'Nam Dinh';
console.log(original.location.city); // "Nam Dinh"

Arrays behave the same way:

1
const copy = [...originalArray];

The array container is new, but nested objects inside it are still shared.

Deep cloning with structuredClone

For supported data types, use the platform API:

1
2
3
4
const clone = structuredClone(original);
clone.location.city = 'Nam Dinh';

console.log(original.location.city); // "Saigon"

structuredClone handles circular references and many built-in types such as Date, Map, Set, ArrayBuffer, and typed arrays. It does not clone functions, DOM nodes, or every custom runtime object.

Why JSON cloning is not general-purpose cloning

1
const clone = JSON.parse(JSON.stringify(value));

This is a serialization round trip, not a complete clone algorithm. It loses or changes values such as:

  • undefined, functions, and symbols;
  • Date objects, which become strings;
  • Map and Set;
  • NaN and Infinity;
  • circular references, which throw an error.

Use it only when the value is intentionally JSON-compatible.

Often, do not clone at all

Deep cloning a large object can be expensive and may hide unclear ownership. Prefer immutable updates that copy only the path being changed:

1
2
3
4
5
6
7
const updated = {
...original,
location: {
...original.location,
city: 'Nam Dinh',
},
};

The real question is not “Which cloning trick is fastest?” It is “Which parts of this data should be shared, and which parts should have independent ownership?” Once that is clear, the code usually becomes boring—which is excellent news for state management.

References