====== Rest vs Spread operator ======
The **rest operator (...)** and the **spread operator (...)** in JavaScript are written the same way but are used for two different purposes. \\
Their usage depends on the context, and they perform opposite operations.
**Rest Operator**: Collects multiple elements into an array. \\
**Spread Operator**: Spreads the elements of an iterable out into individual elements.
===== Rest operator (...) =====
The rest operator is used to **collect all remaining iterable elements into an array or object**.
==== Usage in function arguments ====
This can be particularly useful in function signatures. \\
Example:
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // Output: 15
Here, the **...numbers** argument takes all passed numbers and puts them into an **array** called **numbers**.
Rest function parameter should be the last one in the list:
function validFunction(param1, param2, ...rest) {
console.log(param1, param2, rest);
}
A function cannot have multiple rest parameters.
==== Destructuring Arrays ====
You can use the rest operator to collect the rest of the elements into an array when destructuring:
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(rest); // Output: [3, 4, 5]
==== Destructuring Objects ====
Similarly, when destructuring objects, the rest operator can collect the remaining own enumerable property keys into a new object:
const {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
console.log(rest); // Output: {c: 3, d: 4}
==== Clone Objects and Arrays ====
It's a handy way to create a shallow copy of an object or an array.
const obj = {a: 1, b: 2};
const clonedObj = {...obj}; // Output: {a: 1, b: 2}
===== Spread operator (...) =====
The spread operator is used to **expand elements of an iterable (such as an array, object, or string)** where zero or more arguments (for function calls), elements (for array literals), or key-value pairs (for object literals) are expected. \\
==== Example with Arrays ====
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // Output: [1, 2, 3, 4, 5]
Here, the **...arr1** spreads out the elements of **arr1**, so they become individual elements in **arr2**.
==== Example with Objects ====
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 };
console.log(obj2); // Output: { a: 1, b: 2, c: 3 }
Here, the **...obj1** spreads out the properties of **obj1**, so they become individual properties in **obj2**.