Oscar te Giffel®
← Writing

How to Copy an Object in Javascript.

JavaScript is full of nuances, and copying objects is one of those things that’s deceptively simple. Here’s how it’s evolved.

ES5 Clone Function

In ES5, we’d write a custom clone function:

// ES5 clone function
function clone(obj) {
  if (null == obj || "object" != typeof obj) return obj;
  var copy = obj.constructor();
  for (var attr in obj) {
    if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
  }
  return copy;
}

var obj = { a: 1, b: 2, c: [1, 2, 3] };
var copy = clone(obj);

ES6 Spread Operator

With ES6, the spread operator made it cleaner:

// ES6 spread operator
const obj = { a: 1, b: 2, c: [1, 2, 3] };
const copy = { ...obj };

Both of these create a shallow copy. And that’s where it gets tricky.

Shallow Copy Issue

A shallow copy only duplicates the first level:

const obj = { a: 1, b: 2, c: [1, 2, 3] };
const copy = { ...obj };
copy.c.push(4);
console.log(obj.c); // Output: [1, 2, 3, 4]
console.log(copy.c); // Output: [1, 2, 3, 4]

Modifying copy.c also changes obj.c because they point to the same array. This has bitten me more than once.

Deep Copy with JSON Methods

The classic workaround for deep copying:

const obj = { a: 1, b: 2, c: [1, 2, 3] };
const copy = JSON.parse(JSON.stringify(obj));
copy.a = 3;
console.log(obj.a); // Output: 1
console.log(copy.a); // Output: 3

It works, but it’s slow and can’t handle functions, undefined, Date objects, or circular references.

Deep Copy with structuredClone

The right answer today is structuredClone:

const obj = { a: 1, b: 2, c: [1, 2, 3] };
const copy = structuredClone(obj);
copy.a = 3;
console.log(obj.a); // Output: 1
console.log(copy.a); // Output: 3

It’s fast, handles all data types, deals with circular references, and is supported by all major browsers.

Note: structuredClone does not clone functions, DOM nodes, property descriptors, setters, or getters. The prototype chain is also not duplicated, so the clone is no longer an instance of the original class.

Use structuredClone. That’s it. That’s the conclusion.