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.
The rest operator is used to collect all remaining iterable elements into an array or object.
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.
function validFunction(param1, param2, ...rest) { console.log(param1, param2, rest); }
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]
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}
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}
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.
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.
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.