💯 What is the Spread-Operator in JavaScript?
The Spread operator in JavaScript (...
) splits iterable objects. It was introduced in ES6 (ECMAScript 2015) and is often used to copy, merge, or extend the contents of arrays or objects.
Basic use of the spread operator
Arrays:
- The spread operator can be used to “split” arrays into their individual elements.
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
Objects:
- It can also be used to copy or merge objects.
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
Using the spread operator to delete or overwrite properties
The spread operator is often used to “clone” an object, and then you can either overwrite or delete properties by simply omitting them from the new object.
Overwrite property
To overwrite a property, simply add the new property after the original object’s spread operator. This will then overwrite the original property.
const user = { name: "John", age: 30, city: "Berlin" };
const updatedUser = { ...user, age: 31 }; // age is overwritten
console.log(updatedUser); // { name: "John", age: 31, city: "Berlin" }
In this example, the age
property is updated from 30 to 31, while the other properties remain unchanged.
Delete property
Since the spread operator does not allow direct deletion of properties, removing a property is achieved by assigning a new object that no longer contains the property. The destructuring assignment
syntax helps here:
const user = { name: "John", age: 30, city: "Berlin" };
const { city, ...userWithoutCity } = user; // "city" is removed
console.log(userWithoutCity); // { name: "John", age: 30 }
Here the property city
is extracted and not used in the new object userWithoutCity
.
Using the spread operator for deep copy
A shallow copy can be made using the spread operator, but it is important to note that the spread operator only makes a shallow copy of arrays or objects. For nested objects, only the top level is copied, while deeper objects are still copied by reference.
Shallow copy with the spread operator
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
shallowCopy.b.c = 3;
console.log(original.b.c); // 3, since it is just a shallow copy
In this case, the inner object { c: 2 }
is not actually copied, only the reference to it, which means that changes in the copy also affect the original.
Deep Copy with the Spread Operator
To create a deep copy, all nested objects must also be copied. This can be done manually, or by combining with methods like JSON.parse()
and JSON.stringify()
.
const original = { a: 1, b: { c: 2 } };
// Deep Copy using JSON
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 3;
console.log(original.b.c); // 2, since the original remains unchanged
Using JSON.parse(JSON.stringify(...))
creates a deep copy of an object, but has the disadvantage of losing functions, undefined
and other special types.
Deep copy with recursive copy and spread operator
A recursive approach can be combined with the spread operator to create a deep copy manually:
function deepCopy(obj) {
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
copy[key] = deepCopy(obj[key]); // Recursion for deep objects
} else {
copy[key] = obj[key]; // Copy primitive values
}
}
return copy;
}
const original = {
a: 1,
b: {
c: 2,
d: {
e: 3
}
}
};
const deepCopyObject = deepCopy(original);
deepCopyObject.b.d.e = 4;
console.log(original.b.d.e); // 3, since the original remains unchanged
This approach does not use the spread operator directly for the deep copy, but recursively copies all nested objects.
Summary
-
The spread operator (
...
) is used to copy, extend or merge arrays or objects. -
Overriding properties can be done simply by assigning after the spread operator.
- Deleting properties can be achieved by destructuring.
- Deep copy requires additional approaches like
JSON.parse(JSON.stringify(...))
or recursive copies, since the spread operator only creates a shallow copy.
The spread operator is particularly useful for succinct and clean handling of data structures in JavaScript.