How to Copy an Object in JavaScript

How to Copy an Object in JavaScript

Introduction

In JavaScript, objects are reference types, which means that when you assign an object to another variable, you’re not creating a new copy of the object. Instead, you’re creating a reference to the same object in memory. This can lead to unintended side effects if you modify the object through one of its references. To avoid this, you can create a copy of an object. There are several ways to do this, and each has its own use cases.

Shallow Copy vs. Deep Copy

Before diving into the methods, it’s important to understand the difference between a shallow copy and a deep copy:

  • Shallow Copy: A new object is created, and the properties of the original object are copied to the new object. However, if the properties are themselves objects, they are still references to the same objects in memory.
  • Deep Copy: A new object is created, and all nested objects are also copied, creating entirely independent copies.

Methods to Copy an Object

1. Using Object Literal

The simplest way to create a shallow copy is by creating a new object and copying each property manually.

const original = { name: 'Alice', age: 30 };
const copy = { name: original.name, age: original.age };

console.log(copy); // Output: { name: 'Alice', age: 30 }

2. Using the Spread Operator

The spread operator (...) is a more concise way to create a shallow copy of an object.

const original = { name: 'Alice', age: 30 };
const copy = { ...original };

console.log(copy); // Output: { name: 'Alice', age: 30 }

3. Using Object.assign()

Object.assign() is another method to create a shallow copy. It copies all enumerable properties from the source object to the target object.

const original = { name: 'Alice', age: 30 };
const copy = Object.assign({}, original);

console.log(copy); // Output: { name: 'Alice', age: 30 }

4. Using JSON.parse() and JSON.stringify()

This method creates a deep copy by converting the object to a JSON string and then parsing it back into an object. However, this method has limitations, such as handling circular references or special objects (like Date, RegExp, etc.).

const original = { name: 'Alice', age: 30 };
const copy = JSON.parse(JSON.stringify(original));

console.log(copy); // Output: { name: 'Alice', age: 30 }

5. Using a Custom Deep Copy Function

For more complex objects or to handle edge cases, you can create a custom function to perform a deep copy.

function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  const copy = Array.isArray(obj) ? [] : {};

  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }

  return copy;
}

const original = { name: 'Alice', age: 30, address: { city: 'New York' } };
const copy = deepCopy(original);

console.log(copy); // Output: { name: 'Alice', age: 30, address: { city: 'New York' } }

When to Use Each Method

  • Shallow Copy: Use when the object does not contain nested objects or when you want to share nested objects between copies.
  • Deep Copy: Use when you need an entirely independent copy of the object, including all nested objects.

Frequently Asked Questions

Q: What is the difference between Object.assign() and the spread operator?

A: Both methods are similar and create a shallow copy. The spread operator is more concise and can be used in object literals, while Object.assign() is more flexible and can handle multiple sources.

Q: Can I use the spread operator to copy an array?

A: Yes, the spread operator can also be used to create a copy of an array.

const original = [1, 2, 3];
const copy = [...original];

Q: What happens if I try to copy an object with circular references using JSON.parse() and JSON.stringify()?

A: It will result in an error because JSON.stringify() cannot handle circular references. For such cases, a custom deep copy function is recommended.

Conclusion

Copying objects in JavaScript is essential to avoid unintended side effects when working with reference types. Depending on your needs, you can choose between shallow copy methods like the spread operator or Object.assign(), or deep copy methods like JSON.parse() and JSON.stringify() or a custom function. Always consider the structure of your objects and the requirements of your application when choosing the appropriate method.

Index
Scroll to Top