To copy objects in JavaScript, you typically have three options: using the assignment operator (=)
for reference copying, performing a shallow copy using methods like Object.assign()
or the spread operator (...)
, and creating a deep copy using a combination of JSON.parse() and JSON.stringify()
.
1. Reference Copy (Assignment Operator =):
const originalObject = { key: 'value' };
const referenceCopy = originalObject;
In this method, referenceCopy now points to the same object as originalObject. Changes made to one will affect the other.This method creates a reference to the original object. Changes made to the original object will be reflected in the copied object, and vice versa. This is not a true copy; rather, both variables point to the same object.
2. Shallow Copy:
a. Using Object.assign():
const originalObject = { key: 'value' };
const shallowCopy = Object.assign({}, originalObject);
Object.assign()
creates a shallow copy of the object. It copies the enumerable properties from one or more source objects to a target object. In the example above, an empty object {}
serves as the target, and originalObject
is the source. Note that nested objects are still referenced, so changes to nested objects in the original will affect the copied object.
b. Using Spread Operator (…):
const originalObject = { key: 'value' };
const shallowCopy = { ...originalObject };
The spread operator is a concise way to create shallow copies of objects. Like Object.assign()
, it only creates a copy of the top-level properties. Nested objects are still referenced, so changes to nested objects in the original will affect the copied object.
Both of these methods create a shallow copy, copying only the top-level properties of the object. Changes to nested objects will be reflected in both the original and the copy.
3. Deep Copy:
Using JSON.parse() and JSON.stringify()
const originalObject = { key: 'value', nested: { key2: 'value2' } };
// Using JSON.parse() and JSON.stringify()
const deepCopy = JSON.parse(JSON.stringify(originalObject));
This method creates a deep copy of the object, including nested structures. Keep in mind that this approach has limitations, such as not preserving non-JSON-safe data and being less efficient for large or complex objects.
Select the suitable approach depending on your particular circumstances:
- Reference Copy (=): Use when you want both variables to reference the same object.
- Shallow Copy (Object.assign() or Spread Operator): Use when you need a copy of the top-level properties and are not concerned about nested objects being shared.
- Deep Copy (JSON.parse() and JSON.stringify()): Use when you need a completely independent copy, including nested structures. Be cautious about limitations with non-JSON-safe data.
A glance at examples
// Shallow Copy Example
let product = {
id: 1,
name: 'Smartphone',
price: 499.99,
details: {
brand: 'TechCo',
model: 'SmartX1',
specifications: {
display: '6.2 inches',
camera: '12 MP',
storage: '64 GB'
}
}
};
// Shallow copy using the spread operator
let copiedProduct = { ...product };
copiedProduct.name = 'Smartwatch'; // Disconnected
// Changes in the nested object are connected
copiedProduct.details.model = 'WatchPro';
copiedProduct.details.specifications.display = '1.3 inches';
console.log("Shallow Copy - Copied Product:", copiedProduct);
console.log("Shallow Copy - Original Product:", product);
// Deep Copy Example
let productDeep = {
id: 1,
name: 'Smartphone',
price: 499.99,
details: {
brand: 'TechCo',
model: 'SmartX1',
specifications: {
display: '6.2 inches',
camera: '12 MP',
storage: '64 GB'
}
}
};
// Deep copy using JSON methods
let copiedProductDeep = JSON.parse(JSON.stringify(productDeep));
copiedProductDeep.name = 'Laptop'; // Disconnected
// Changes in the nested object are also disconnected
copiedProductDeep.details.model = 'LaptopPro';
copiedProductDeep.details.specifications.display = '15.6 inches';
console.log("Deep Copy - Copied Product:", copiedProductDeep);
console.log("Deep Copy - Original Product:", productDeep);