Rest syntax looks exactly like spread syntax. In a way, rest syntax is the opposite of spread syntax. Spread syntax “expands” an array into its elements, while rest syntax collects multiple elements and “condenses” them into a single element.
Table of Contents
Rest Parameter:
The rest parameter syntax allows us to represent an indefinite number of arguments as an array.
Syntax
function f(a, b, ...theArgs) { // ... }
We can call a function with less or more number of parameter than function can accept. It will not give any error. But we can use with in function only number of parameter accept by function.
function sum(a, b) { return a + b; } console.log(sum(1, 2)); // expected output: 3 console.log(sum(1, 2, 3, 4)); // expected output: 3
A function’s last parameter can be prefixed with ...
which help to accept all extra parameter in the form of array, which we can use with in function.
function myFun(a, b, ...manyMoreArgs) { console.log("a", a) console.log("b", b) console.log("manyMoreArgs", manyMoreArgs) } myFun("one", "two", "three", "four", "five", "six") // Console Output: // a, one // b, two // manyMoreArgs, [three, four, five, six]
In above example, the first argument is mapped to a
and the second to b
, so these named arguments are used as normal.
However, the third argument, manyMoreArgs
, will be an array that contains the 3rd, 4th, 5th, 6th … nth — as many arguments that the user includes.
The rest parameters must be at the end
function f(a, ...theArgs, b) { // error } f(1,2,3,4) // Uncaught SyntaxError: Rest parameter must be last formal parameter
What is earlier rest parameter ?
Earlier then rest parameter, there is the way of handling is “arguments”. But there is a difference between rest and arguments.
function sortArguments() { return arguments } console.log(sortArguments(5, 3, 7, 1)) // Arguments(4) [5, 3, 7, 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]
Let see one more example where we are passing parameter also and we see that parameter got there value also but “arguments” also receive all passed argument.
function sortArguments(a,b) { console.log(a,b) // 5,3 return arguments } console.log(sortArguments(5, 3, 7, 1)) // Arguments(4) [5, 3, 7, 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]
To use
Array
methods on thearguments
object, it must be converted to a real array first. Since arguments is not array.
function sortArguments() { let args = Array.from(arguments) let sortedArgs = args.sort() return sortedArgs } console.log(sortArguments(5, 3, 7, 1)) // 1, 3, 5, 7
Difference between rest parameters and the arguments
object
There are three main differences between rest parameters and the arguments
object:
- rest parameters are only the ones that haven’t been given a separate name (i.e. formally defined in function expression), while the
arguments
object contains all arguments passed to the function; - the
arguments
object is not a real array, while rest parameters areArray
instances, meaning methods likesort
,map
,forEach
orpop
can be applied to it directly; - the
arguments
object has additional functionality specific to itself (like thecallee
property).
Spread Syntax:
Spread syntax (…) allows you to expand any iterable like an array or string in place.
Spread syntax (
MDN...
) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
function sum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; console.log(sum(...numbers)); // expected output: 6
Syntax:
For function calls:
myFunction(...iterableObj);
For array literals or strings:
[...iterableObj, '4', 'five', 6];
For object literals (new in ECMAScript 2018):
let objClone = { ...obj };
Spread in array literals:
The spread syntax very helpful while using with array. Many times we can replace push(), concat() array method.
let str = "Hello"; console.log( [...str] ); // [H,e,l,l,o]
Merging two array:
const parts = ['shoulders', 'knees']; const lyrics = ['head', ...parts, 'and', 'toes']; // ["head", "shoulders", "knees", "and", "toes"]
let arr1 = [0, 1, 2]; let arr2 = [3, 4, 5]; arr1 = [...arr2, 7,8,9, ...arr1]; // arr1 is now [3, 4, 5, 7,8,9,0, 1, 2]
Copy an array:
const arr = [1, 2, 3]; const arr2 = [...arr]; // like arr.slice() arr2.push(4); // arr2 becomes [1, 2, 3, 4] // arr remains unaffected
Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays
Point to Remember
Spread in object literals:
const obj1 = { foo: 'bar', x: 42 }; const clonedObj = { ...obj1 }; // // Object { foo: "bar", x: 42 }
const obj1 = { foo: 'bar', x: 42 }; const obj2 = { foo: 'baz', y: 13 }; const mergedObj = { ...obj1, ...obj2 }; // // Object { foo: "baz", x: 42, y: 13 }
Spread syntax (other than in the case of spread properties) can be applied only to iterable objects:
const obj = {'key1': 'value1'}; const array = [...obj]; // TypeError: obj is not iterable
Spread in function calls:
function myFunction(x, y, z) { } const args = [0, 1, 2]; myFunction(...args);
It is common to use
Function.prototype.apply()
in cases where you want to use the elements of an array as arguments to a function. But now you can use spread syntax.
function myFunction(x, y, z) { } const args = [0, 1, 2]; myFunction.apply(null, args);
When calling a constructor with new
it’s not possible to directly use an array and apply()
. However, an array can be easily used with spread syntax:
const dateFields = [1970, 0, 1]; // 1 Jan 1970 const d = new Date(...dateFields);
Rest syntax looks exactly like spread syntax. In a way, rest syntax is the opposite of spread syntax. Spread syntax “expands” an array into its elements, while rest syntax collects multiple elements and “condenses” them into a single element