====== 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**.